diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/arc/kernel/unaligned.c linux-libre-4.10-rc8-gnu/arch/arc/kernel/unaligned.c
--- linux-libre-4.10-rc7-gnu/arch/arc/kernel/unaligned.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/arc/kernel/unaligned.c	2017-02-12 16:03:20.000000000 -0500
@@ -243,7 +243,7 @@ int misaligned_fixup(unsigned long addre
 
 	/* clear any remanants of delay slot */
 	if (delay_mode(regs)) {
-		regs->ret = regs->bta ~1U;
+		regs->ret = regs->bta & ~1U;
 		regs->status32 &= ~STATUS_DE_MASK;
 	} else {
 		regs->ret += state.instr_len;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx1.dtsi linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx1.dtsi
--- linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx1.dtsi	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx1.dtsi	2017-02-12 16:03:20.000000000 -0500
@@ -18,6 +18,14 @@
 / {
 	#address-cells = <1>;
 	#size-cells = <1>;
+	/*
+	 * The decompressor and also some bootloaders rely on a
+	 * pre-existing /chosen node to be available to insert the
+	 * command line and merge other ATAGS info.
+	 * Also for U-Boot there must be a pre-existing /memory node.
+	 */
+	chosen {};
+	memory { device_type = "memory"; reg = <0 0>; };
 
 	aliases {
 		gpio0 = &gpio1;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx23.dtsi linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx23.dtsi
--- linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx23.dtsi	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx23.dtsi	2017-02-12 16:03:20.000000000 -0500
@@ -16,6 +16,14 @@
 	#size-cells = <1>;
 
 	interrupt-parent = <&icoll>;
+	/*
+	 * The decompressor and also some bootloaders rely on a
+	 * pre-existing /chosen node to be available to insert the
+	 * command line and merge other ATAGS info.
+	 * Also for U-Boot there must be a pre-existing /memory node.
+	 */
+	chosen {};
+	memory { device_type = "memory"; reg = <0 0>; };
 
 	aliases {
 		gpio0 = &gpio0;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx25.dtsi linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx25.dtsi
--- linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx25.dtsi	2017-02-06 10:49:55.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx25.dtsi	2017-02-12 17:27:04.000000000 -0500
@@ -14,6 +14,14 @@
 / {
 	#address-cells = <1>;
 	#size-cells = <1>;
+	/*
+	 * The decompressor and also some bootloaders rely on a
+	 * pre-existing /chosen node to be available to insert the
+	 * command line and merge other ATAGS info.
+	 * Also for U-Boot there must be a pre-existing /memory node.
+	 */
+	chosen {};
+	memory { device_type = "memory"; reg = <0 0>; };
 
 	aliases {
 		ethernet0 = &fec;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx27.dtsi linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx27.dtsi
--- linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx27.dtsi	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx27.dtsi	2017-02-12 16:03:20.000000000 -0500
@@ -19,6 +19,14 @@
 / {
 	#address-cells = <1>;
 	#size-cells = <1>;
+	/*
+	 * The decompressor and also some bootloaders rely on a
+	 * pre-existing /chosen node to be available to insert the
+	 * command line and merge other ATAGS info.
+	 * Also for U-Boot there must be a pre-existing /memory node.
+	 */
+	chosen {};
+	memory { device_type = "memory"; reg = <0 0>; };
 
 	aliases {
 		ethernet0 = &fec;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx28.dtsi linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx28.dtsi
--- linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx28.dtsi	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx28.dtsi	2017-02-12 16:03:20.000000000 -0500
@@ -17,6 +17,14 @@
 	#size-cells = <1>;
 
 	interrupt-parent = <&icoll>;
+	/*
+	 * The decompressor and also some bootloaders rely on a
+	 * pre-existing /chosen node to be available to insert the
+	 * command line and merge other ATAGS info.
+	 * Also for U-Boot there must be a pre-existing /memory node.
+	 */
+	chosen {};
+	memory { device_type = "memory"; reg = <0 0>; };
 
 	aliases {
 		ethernet0 = &mac0;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx31.dtsi linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx31.dtsi
--- linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx31.dtsi	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx31.dtsi	2017-02-12 16:03:20.000000000 -0500
@@ -12,6 +12,14 @@
 / {
 	#address-cells = <1>;
 	#size-cells = <1>;
+	/*
+	 * The decompressor and also some bootloaders rely on a
+	 * pre-existing /chosen node to be available to insert the
+	 * command line and merge other ATAGS info.
+	 * Also for U-Boot there must be a pre-existing /memory node.
+	 */
+	chosen {};
+	memory { device_type = "memory"; reg = <0 0>; };
 
 	aliases {
 		serial0 = &uart1;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx35.dtsi linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx35.dtsi
--- linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx35.dtsi	2017-02-06 10:49:57.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx35.dtsi	2017-02-12 17:27:07.000000000 -0500
@@ -13,6 +13,14 @@
 / {
 	#address-cells = <1>;
 	#size-cells = <1>;
+	/*
+	 * The decompressor and also some bootloaders rely on a
+	 * pre-existing /chosen node to be available to insert the
+	 * command line and merge other ATAGS info.
+	 * Also for U-Boot there must be a pre-existing /memory node.
+	 */
+	chosen {};
+	memory { device_type = "memory"; reg = <0 0>; };
 
 	aliases {
 		ethernet0 = &fec;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx50.dtsi linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx50.dtsi
--- linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx50.dtsi	2017-02-06 10:50:00.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx50.dtsi	2017-02-12 17:27:09.000000000 -0500
@@ -17,6 +17,14 @@
 / {
 	#address-cells = <1>;
 	#size-cells = <1>;
+	/*
+	 * The decompressor and also some bootloaders rely on a
+	 * pre-existing /chosen node to be available to insert the
+	 * command line and merge other ATAGS info.
+	 * Also for U-Boot there must be a pre-existing /memory node.
+	 */
+	chosen {};
+	memory { device_type = "memory"; reg = <0 0>; };
 
 	aliases {
 		ethernet0 = &fec;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx51.dtsi linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx51.dtsi
--- linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx51.dtsi	2017-02-06 10:50:02.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx51.dtsi	2017-02-12 17:27:12.000000000 -0500
@@ -19,6 +19,14 @@
 / {
 	#address-cells = <1>;
 	#size-cells = <1>;
+	/*
+	 * The decompressor and also some bootloaders rely on a
+	 * pre-existing /chosen node to be available to insert the
+	 * command line and merge other ATAGS info.
+	 * Also for U-Boot there must be a pre-existing /memory node.
+	 */
+	chosen {};
+	memory { device_type = "memory"; reg = <0 0>; };
 
 	aliases {
 		ethernet0 = &fec;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx53.dtsi linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx53.dtsi
--- linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx53.dtsi	2017-02-06 10:50:05.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx53.dtsi	2017-02-12 17:27:15.000000000 -0500
@@ -19,6 +19,14 @@
 / {
 	#address-cells = <1>;
 	#size-cells = <1>;
+	/*
+	 * The decompressor and also some bootloaders rely on a
+	 * pre-existing /chosen node to be available to insert the
+	 * command line and merge other ATAGS info.
+	 * Also for U-Boot there must be a pre-existing /memory node.
+	 */
+	chosen {};
+	memory { device_type = "memory"; reg = <0 0>; };
 
 	aliases {
 		ethernet0 = &fec;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx6dl.dtsi linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx6dl.dtsi
--- linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx6dl.dtsi	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx6dl.dtsi	2017-02-12 16:03:20.000000000 -0500
@@ -137,7 +137,7 @@
 &gpio4 {
 	gpio-ranges = <&iomuxc  5 136 1>, <&iomuxc  6 145 1>, <&iomuxc  7 150 1>,
 		      <&iomuxc  8 146 1>, <&iomuxc  9 151 1>, <&iomuxc 10 147 1>,
-		      <&iomuxc 11 151 1>, <&iomuxc 12 148 1>, <&iomuxc 13 153 1>,
+		      <&iomuxc 11 152 1>, <&iomuxc 12 148 1>, <&iomuxc 13 153 1>,
 		      <&iomuxc 14 149 1>, <&iomuxc 15 154 1>, <&iomuxc 16  39 7>,
 		      <&iomuxc 23  56 1>, <&iomuxc 24  61 7>, <&iomuxc 31  46 1>;
 };
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx6qdl.dtsi linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx6qdl.dtsi
--- linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx6qdl.dtsi	2017-02-06 10:50:10.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx6qdl.dtsi	2017-02-12 17:27:20.000000000 -0500
@@ -16,6 +16,14 @@
 / {
 	#address-cells = <1>;
 	#size-cells = <1>;
+	/*
+	 * The decompressor and also some bootloaders rely on a
+	 * pre-existing /chosen node to be available to insert the
+	 * command line and merge other ATAGS info.
+	 * Also for U-Boot there must be a pre-existing /memory node.
+	 */
+	chosen {};
+	memory { device_type = "memory"; reg = <0 0>; };
 
 	aliases {
 		ethernet0 = &fec;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx6sl.dtsi linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx6sl.dtsi
--- linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx6sl.dtsi	2017-02-06 10:50:13.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx6sl.dtsi	2017-02-12 17:27:23.000000000 -0500
@@ -14,6 +14,14 @@
 / {
 	#address-cells = <1>;
 	#size-cells = <1>;
+	/*
+	 * The decompressor and also some bootloaders rely on a
+	 * pre-existing /chosen node to be available to insert the
+	 * command line and merge other ATAGS info.
+	 * Also for U-Boot there must be a pre-existing /memory node.
+	 */
+	chosen {};
+	memory { device_type = "memory"; reg = <0 0>; };
 
 	aliases {
 		ethernet0 = &fec;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx6sx.dtsi linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx6sx.dtsi
--- linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx6sx.dtsi	2017-02-06 10:50:16.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx6sx.dtsi	2017-02-12 17:27:31.000000000 -0500
@@ -15,6 +15,14 @@
 / {
 	#address-cells = <1>;
 	#size-cells = <1>;
+	/*
+	 * The decompressor and also some bootloaders rely on a
+	 * pre-existing /chosen node to be available to insert the
+	 * command line and merge other ATAGS info.
+	 * Also for U-Boot there must be a pre-existing /memory node.
+	 */
+	chosen {};
+	memory { device_type = "memory"; reg = <0 0>; };
 
 	aliases {
 		can0 = &flexcan1;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx6ul.dtsi linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx6ul.dtsi
--- linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx6ul.dtsi	2017-02-06 10:50:19.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx6ul.dtsi	2017-02-12 17:27:42.000000000 -0500
@@ -15,6 +15,14 @@
 / {
 	#address-cells = <1>;
 	#size-cells = <1>;
+	/*
+	 * The decompressor and also some bootloaders rely on a
+	 * pre-existing /chosen node to be available to insert the
+	 * command line and merge other ATAGS info.
+	 * Also for U-Boot there must be a pre-existing /memory node.
+	 */
+	chosen {};
+	memory { device_type = "memory"; reg = <0 0>; };
 
 	aliases {
 		ethernet0 = &fec1;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx7s.dtsi linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx7s.dtsi
--- linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/imx7s.dtsi	2017-02-06 10:50:22.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/imx7s.dtsi	2017-02-12 17:27:46.000000000 -0500
@@ -50,6 +50,14 @@
 / {
 	#address-cells = <1>;
 	#size-cells = <1>;
+	/*
+	 * The decompressor and also some bootloaders rely on a
+	 * pre-existing /chosen node to be available to insert the
+	 * command line and merge other ATAGS info.
+	 * Also for U-Boot there must be a pre-existing /memory node.
+	 */
+	chosen {};
+	memory { device_type = "memory"; reg = <0 0>; };
 
 	aliases {
 		gpio0 = &gpio1;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/Makefile linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/Makefile
--- linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/Makefile	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/Makefile	2017-02-12 16:03:20.000000000 -0500
@@ -617,7 +617,7 @@ dtb-$(CONFIG_ARCH_ORION5X) += \
 	orion5x-lacie-ethernet-disk-mini-v2.dtb \
 	orion5x-linkstation-lsgl.dtb \
 	orion5x-linkstation-lswtgl.dtb \
-	orion5x-lschl.dtb \
+	orion5x-linkstation-lschl.dtb \
 	orion5x-lswsgl.dtb \
 	orion5x-maxtor-shared-storage-2.dtb \
 	orion5x-netgear-wnr854t.dtb \
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/orion5x-linkstation-lschl.dts linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/orion5x-linkstation-lschl.dts
--- linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/orion5x-linkstation-lschl.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/orion5x-linkstation-lschl.dts	2017-02-12 16:03:20.000000000 -0500
@@ -0,0 +1,171 @@
+/*
+ * Device Tree file for Buffalo Linkstation LS-CHLv3
+ *
+ * Copyright (C) 2016 Ash Hughes <ashley.hughes@blueyonder.co.uk>
+ * Copyright (C) 2015-2017
+ * Roger Shimizu <rogershimizu@gmail.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include "orion5x-linkstation.dtsi"
+#include "mvebu-linkstation-gpio-simple.dtsi"
+#include "mvebu-linkstation-fan.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	model = "Buffalo Linkstation LiveV3 (LS-CHL)";
+	compatible = "buffalo,lschl", "marvell,orion5x-88f5182", "marvell,orion5x";
+
+	memory { /* 128 MB */
+		device_type = "memory";
+		reg = <0x00000000 0x8000000>;
+	};
+
+	gpio_keys {
+		func {
+			label = "Function Button";
+			linux,code = <KEY_OPTION>;
+			gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
+		};
+
+		power-on-switch {
+			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+		};
+
+		power-auto-switch {
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio_leds {
+		pinctrl-0 = <&pmx_led_power &pmx_led_alarm &pmx_led_info &pmx_led_func>;
+		blue-power-led {
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+		};
+
+		red-alarm-led {
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+		};
+
+		amber-info-led {
+			gpios = <&gpio0 3 GPIO_ACTIVE_LOW>;
+		};
+
+		func {
+			label = "lschl:func:blue:top";
+			gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio_fan {
+		gpios = <&gpio0 14 GPIO_ACTIVE_LOW
+			 &gpio0 16 GPIO_ACTIVE_LOW>;
+
+		alarm-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+	};
+};
+
+&pinctrl {
+	pmx_led_power: pmx-leds {
+		marvell,pins = "mpp0";
+		marvell,function = "gpio";
+	};
+
+	pmx_power_hdd: pmx-power-hdd {
+		marvell,pins = "mpp1";
+		marvell,function = "gpio";
+	};
+
+	pmx_led_alarm: pmx-leds {
+		marvell,pins = "mpp2";
+		marvell,function = "gpio";
+	};
+
+	pmx_led_info: pmx-leds {
+		marvell,pins = "mpp3";
+		marvell,function = "gpio";
+	};
+
+	pmx_fan_lock: pmx-fan-lock {
+		marvell,pins = "mpp6";
+		marvell,function = "gpio";
+	};
+
+	pmx_power_switch: pmx-power-switch {
+		marvell,pins = "mpp8", "mpp10", "mpp15";
+		marvell,function = "gpio";
+	};
+
+	pmx_power_usb: pmx-power-usb {
+		marvell,pins = "mpp9";
+		marvell,function = "gpio";
+	};
+
+	pmx_fan_high: pmx-fan-high {
+		marvell,pins = "mpp14";
+		marvell,function = "gpio";
+	};
+
+	pmx_fan_low: pmx-fan-low {
+		marvell,pins = "mpp16";
+		marvell,function = "gpio";
+	};
+
+	pmx_led_func: pmx-leds {
+		marvell,pins = "mpp17";
+		marvell,function = "gpio";
+	};
+
+	pmx_sw_init: pmx-sw-init {
+		marvell,pins = "mpp7";
+		marvell,function = "gpio";
+	};
+};
+
+&hdd_power {
+	gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>;
+};
+
+&usb_power {
+	gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
+};
+
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/orion5x-lschl.dts linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/orion5x-lschl.dts
--- linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/orion5x-lschl.dts	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/orion5x-lschl.dts	1969-12-31 19:00:00.000000000 -0500
@@ -1,171 +0,0 @@
-/*
- * Device Tree file for Buffalo Linkstation LS-CHLv3
- *
- * Copyright (C) 2016 Ash Hughes <ashley.hughes@blueyonder.co.uk>
- * Copyright (C) 2015, 2016
- * Roger Shimizu <rogershimizu@gmail.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/dts-v1/;
-
-#include "orion5x-linkstation.dtsi"
-#include "mvebu-linkstation-gpio-simple.dtsi"
-#include "mvebu-linkstation-fan.dtsi"
-#include <dt-bindings/gpio/gpio.h>
-
-/ {
-	model = "Buffalo Linkstation Live v3 (LS-CHL)";
-	compatible = "buffalo,lschl", "marvell,orion5x-88f5182", "marvell,orion5x";
-
-	memory { /* 128 MB */
-		device_type = "memory";
-		reg = <0x00000000 0x8000000>;
-	};
-
-	gpio_keys {
-		func {
-			label = "Function Button";
-			linux,code = <KEY_OPTION>;
-			gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
-		};
-
-		power-on-switch {
-			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
-		};
-
-		power-auto-switch {
-			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
-		};
-	};
-
-	gpio_leds {
-		pinctrl-0 = <&pmx_led_power &pmx_led_alarm &pmx_led_info &pmx_led_func>;
-		blue-power-led {
-			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
-		};
-
-		red-alarm-led {
-			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
-		};
-
-		amber-info-led {
-			gpios = <&gpio0 3 GPIO_ACTIVE_LOW>;
-		};
-
-		func {
-			label = "lschl:func:blue:top";
-			gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
-		};
-	};
-
-	gpio_fan {
-		gpios = <&gpio0 14 GPIO_ACTIVE_LOW
-			 &gpio0 16 GPIO_ACTIVE_LOW>;
-
-		alarm-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
-	};
-};
-
-&pinctrl {
-	pmx_led_power: pmx-leds {
-		marvell,pins = "mpp0";
-		marvell,function = "gpio";
-	};
-
-	pmx_power_hdd: pmx-power-hdd {
-		marvell,pins = "mpp1";
-		marvell,function = "gpio";
-	};
-
-	pmx_led_alarm: pmx-leds {
-		marvell,pins = "mpp2";
-		marvell,function = "gpio";
-	};
-
-	pmx_led_info: pmx-leds {
-		marvell,pins = "mpp3";
-		marvell,function = "gpio";
-	};
-
-	pmx_fan_lock: pmx-fan-lock {
-		marvell,pins = "mpp6";
-		marvell,function = "gpio";
-	};
-
-	pmx_power_switch: pmx-power-switch {
-		marvell,pins = "mpp8", "mpp10", "mpp15";
-		marvell,function = "gpio";
-	};
-
-	pmx_power_usb: pmx-power-usb {
-		marvell,pins = "mpp9";
-		marvell,function = "gpio";
-	};
-
-	pmx_fan_high: pmx-fan-high {
-		marvell,pins = "mpp14";
-		marvell,function = "gpio";
-	};
-
-	pmx_fan_low: pmx-fan-low {
-		marvell,pins = "mpp16";
-		marvell,function = "gpio";
-	};
-
-	pmx_led_func: pmx-leds {
-		marvell,pins = "mpp17";
-		marvell,function = "gpio";
-	};
-
-	pmx_sw_init: pmx-sw-init {
-		marvell,pins = "mpp7";
-		marvell,function = "gpio";
-	};
-};
-
-&hdd_power {
-	gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>;
-};
-
-&usb_power {
-	gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
-};
-
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/stih407-family.dtsi linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/stih407-family.dtsi
--- linux-libre-4.10-rc7-gnu/arch/arm/boot/dts/stih407-family.dtsi	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/arm/boot/dts/stih407-family.dtsi	2017-02-12 16:03:20.000000000 -0500
@@ -680,6 +680,7 @@
 				phy-names	= "usb2-phy", "usb3-phy";
 				phys		= <&usb2_picophy0>,
 						  <&phy_port2 PHY_TYPE_USB3>;
+				snps,dis_u3_susphy_quirk;
 			};
 		};
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/arm/configs/ezx_defconfig linux-libre-4.10-rc8-gnu/arch/arm/configs/ezx_defconfig
--- linux-libre-4.10-rc7-gnu/arch/arm/configs/ezx_defconfig	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/arm/configs/ezx_defconfig	2017-02-12 16:03:20.000000000 -0500
@@ -64,8 +64,8 @@ CONFIG_NETFILTER=y
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NF_CONNTRACK=m
 CONFIG_NF_CONNTRACK_EVENTS=y
-CONFIG_NF_CT_PROTO_SCTP=m
-CONFIG_NF_CT_PROTO_UDPLITE=m
+CONFIG_NF_CT_PROTO_SCTP=y
+CONFIG_NF_CT_PROTO_UDPLITE=y
 CONFIG_NF_CONNTRACK_AMANDA=m
 CONFIG_NF_CONNTRACK_FTP=m
 CONFIG_NF_CONNTRACK_H323=m
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/arm/configs/imote2_defconfig linux-libre-4.10-rc8-gnu/arch/arm/configs/imote2_defconfig
--- linux-libre-4.10-rc7-gnu/arch/arm/configs/imote2_defconfig	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/arm/configs/imote2_defconfig	2017-02-12 16:03:20.000000000 -0500
@@ -56,8 +56,8 @@ CONFIG_NETFILTER=y
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NF_CONNTRACK=m
 CONFIG_NF_CONNTRACK_EVENTS=y
-CONFIG_NF_CT_PROTO_SCTP=m
-CONFIG_NF_CT_PROTO_UDPLITE=m
+CONFIG_NF_CT_PROTO_SCTP=y
+CONFIG_NF_CT_PROTO_UDPLITE=y
 CONFIG_NF_CONNTRACK_AMANDA=m
 CONFIG_NF_CONNTRACK_FTP=m
 CONFIG_NF_CONNTRACK_H323=m
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/arm/kernel/ptrace.c linux-libre-4.10-rc8-gnu/arch/arm/kernel/ptrace.c
--- linux-libre-4.10-rc7-gnu/arch/arm/kernel/ptrace.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/arm/kernel/ptrace.c	2017-02-12 16:03:20.000000000 -0500
@@ -600,7 +600,7 @@ static int gpr_set(struct task_struct *t
 		   const void *kbuf, const void __user *ubuf)
 {
 	int ret;
-	struct pt_regs newregs;
+	struct pt_regs newregs = *task_pt_regs(target);
 
 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
 				 &newregs,
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/arm/mach-imx/mmdc.c linux-libre-4.10-rc8-gnu/arch/arm/mach-imx/mmdc.c
--- linux-libre-4.10-rc7-gnu/arch/arm/mach-imx/mmdc.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/arm/mach-imx/mmdc.c	2017-02-12 16:03:20.000000000 -0500
@@ -60,7 +60,6 @@
 
 #define to_mmdc_pmu(p) container_of(p, struct mmdc_pmu, pmu)
 
-static enum cpuhp_state cpuhp_mmdc_state;
 static int ddr_type;
 
 struct fsl_mmdc_devtype_data {
@@ -82,6 +81,7 @@ static const struct of_device_id imx_mmd
 
 #ifdef CONFIG_PERF_EVENTS
 
+static enum cpuhp_state cpuhp_mmdc_state;
 static DEFINE_IDA(mmdc_ida);
 
 PMU_EVENT_ATTR_STRING(total-cycles, mmdc_pmu_total_cycles, "event=0x00")
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/arm/mm/fault.c linux-libre-4.10-rc8-gnu/arch/arm/mm/fault.c
--- linux-libre-4.10-rc7-gnu/arch/arm/mm/fault.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/arm/mm/fault.c	2017-02-12 16:03:20.000000000 -0500
@@ -610,9 +610,9 @@ static int __init early_abort_handler(un
 
 void __init early_abt_enable(void)
 {
-	fsr_info[22].fn = early_abort_handler;
+	fsr_info[FSR_FS_AEA].fn = early_abort_handler;
 	local_abt_enable();
-	fsr_info[22].fn = do_bad;
+	fsr_info[FSR_FS_AEA].fn = do_bad;
 }
 
 #ifndef CONFIG_ARM_LPAE
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/arm/mm/fault.h linux-libre-4.10-rc8-gnu/arch/arm/mm/fault.h
--- linux-libre-4.10-rc7-gnu/arch/arm/mm/fault.h	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/arm/mm/fault.h	2017-02-12 16:03:20.000000000 -0500
@@ -11,11 +11,15 @@
 #define FSR_FS5_0		(0x3f)
 
 #ifdef CONFIG_ARM_LPAE
+#define FSR_FS_AEA		17
+
 static inline int fsr_fs(unsigned int fsr)
 {
 	return fsr & FSR_FS5_0;
 }
 #else
+#define FSR_FS_AEA		22
+
 static inline int fsr_fs(unsigned int fsr)
 {
 	return (fsr & FSR_FS3_0) | (fsr & FSR_FS4) >> 6;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts linux-libre-4.10-rc8-gnu/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
--- linux-libre-4.10-rc7-gnu/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts	2017-02-12 16:03:20.000000000 -0500
@@ -151,6 +151,18 @@
 	status = "okay";
 	pinctrl-0 = <&eth_rgmii_pins>;
 	pinctrl-names = "default";
+	phy-handle = <&eth_phy0>;
+
+	mdio {
+		compatible = "snps,dwmac-mdio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		eth_phy0: ethernet-phy@0 {
+			reg = <0>;
+			eee-broken-1000t;
+		};
+	};
 };
 
 &ir {
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/arm64/boot/dts/amlogic/meson-gx.dtsi linux-libre-4.10-rc8-gnu/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
--- linux-libre-4.10-rc7-gnu/arch/arm64/boot/dts/amlogic/meson-gx.dtsi	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/arm64/boot/dts/amlogic/meson-gx.dtsi	2017-02-12 16:03:20.000000000 -0500
@@ -55,6 +55,24 @@
 	#address-cells = <2>;
 	#size-cells = <2>;
 
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		/* 16 MiB reserved for Hardware ROM Firmware */
+		hwrom_reserved: hwrom@0 {
+			reg = <0x0 0x0 0x0 0x1000000>;
+			no-map;
+		};
+
+		/* 2 MiB reserved for ARM Trusted Firmware (BL31) */
+		secmon_reserved: secmon@10000000 {
+			reg = <0x0 0x10000000 0x0 0x200000>;
+			no-map;
+		};
+	};
+
 	cpus {
 		#address-cells = <0x2>;
 		#size-cells = <0x0>;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/powerpc/include/asm/reg.h linux-libre-4.10-rc8-gnu/arch/powerpc/include/asm/reg.h
--- linux-libre-4.10-rc7-gnu/arch/powerpc/include/asm/reg.h	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/powerpc/include/asm/reg.h	2017-02-12 16:03:20.000000000 -0500
@@ -649,9 +649,10 @@
 #define   SRR1_ISI_N_OR_G	0x10000000 /* ISI: Access is no-exec or G */
 #define   SRR1_ISI_PROT		0x08000000 /* ISI: Other protection fault */
 #define   SRR1_WAKEMASK		0x00380000 /* reason for wakeup */
-#define   SRR1_WAKEMASK_P8	0x003c0000 /* reason for wakeup on POWER8 */
+#define   SRR1_WAKEMASK_P8	0x003c0000 /* reason for wakeup on POWER8 and 9 */
 #define   SRR1_WAKESYSERR	0x00300000 /* System error */
 #define   SRR1_WAKEEE		0x00200000 /* External interrupt */
+#define   SRR1_WAKEHVI		0x00240000 /* Hypervisor Virtualization Interrupt (P9) */
 #define   SRR1_WAKEMT		0x00280000 /* mtctrl */
 #define	  SRR1_WAKEHMI		0x00280000 /* Hypervisor maintenance */
 #define   SRR1_WAKEDEC		0x00180000 /* Decrementer interrupt */
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/powerpc/include/asm/xics.h linux-libre-4.10-rc8-gnu/arch/powerpc/include/asm/xics.h
--- linux-libre-4.10-rc7-gnu/arch/powerpc/include/asm/xics.h	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/powerpc/include/asm/xics.h	2017-02-12 16:03:20.000000000 -0500
@@ -44,6 +44,7 @@ static inline int icp_hv_init(void) { re
 
 #ifdef CONFIG_PPC_POWERNV
 extern int icp_opal_init(void);
+extern void icp_opal_flush_interrupt(void);
 #else
 static inline int icp_opal_init(void) { return -ENODEV; }
 #endif
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/powerpc/mm/fault.c linux-libre-4.10-rc8-gnu/arch/powerpc/mm/fault.c
--- linux-libre-4.10-rc7-gnu/arch/powerpc/mm/fault.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/powerpc/mm/fault.c	2017-02-12 16:03:20.000000000 -0500
@@ -253,8 +253,11 @@ int do_page_fault(struct pt_regs *regs,
 	if (unlikely(debugger_fault_handler(regs)))
 		goto bail;
 
-	/* On a kernel SLB miss we can only check for a valid exception entry */
-	if (!user_mode(regs) && (address >= TASK_SIZE)) {
+	/*
+	 * The kernel should never take an execute fault nor should it
+	 * take a page fault to a kernel address.
+	 */
+	if (!user_mode(regs) && (is_exec || (address >= TASK_SIZE))) {
 		rc = SIGSEGV;
 		goto bail;
 	}
@@ -391,20 +394,6 @@ good_area:
 
 	if (is_exec) {
 		/*
-		 * An execution fault + no execute ?
-		 *
-		 * On CPUs that don't have CPU_FTR_COHERENT_ICACHE we
-		 * deliberately create NX mappings, and use the fault to do the
-		 * cache flush. This is usually handled in hash_page_do_lazy_icache()
-		 * but we could end up here if that races with a concurrent PTE
-		 * update. In that case we need to fall through here to the VMA
-		 * check below.
-		 */
-		if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE) &&
-			(regs->msr & SRR1_ISI_N_OR_G))
-			goto bad_area;
-
-		/*
 		 * Allow execution from readable areas if the MMU does not
 		 * provide separate controls over reading and executing.
 		 *
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/powerpc/mm/tlb-radix.c linux-libre-4.10-rc8-gnu/arch/powerpc/mm/tlb-radix.c
--- linux-libre-4.10-rc7-gnu/arch/powerpc/mm/tlb-radix.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/powerpc/mm/tlb-radix.c	2017-02-12 16:03:20.000000000 -0500
@@ -50,9 +50,7 @@ static inline void _tlbiel_pid(unsigned
 	for (set = 0; set < POWER9_TLB_SETS_RADIX ; set++) {
 		__tlbiel_pid(pid, set, ric);
 	}
-	if (cpu_has_feature(CPU_FTR_POWER9_DD1))
-		asm volatile(PPC_INVALIDATE_ERAT : : :"memory");
-	return;
+	asm volatile(PPC_INVALIDATE_ERAT "; isync" : : :"memory");
 }
 
 static inline void _tlbie_pid(unsigned long pid, unsigned long ric)
@@ -85,8 +83,6 @@ static inline void _tlbiel_va(unsigned l
 	asm volatile(PPC_TLBIEL(%0, %4, %3, %2, %1)
 		     : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory");
 	asm volatile("ptesync": : :"memory");
-	if (cpu_has_feature(CPU_FTR_POWER9_DD1))
-		asm volatile(PPC_INVALIDATE_ERAT : : :"memory");
 }
 
 static inline void _tlbie_va(unsigned long va, unsigned long pid,
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/powerpc/platforms/powernv/smp.c linux-libre-4.10-rc8-gnu/arch/powerpc/platforms/powernv/smp.c
--- linux-libre-4.10-rc7-gnu/arch/powerpc/platforms/powernv/smp.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/powerpc/platforms/powernv/smp.c	2017-02-12 16:03:20.000000000 -0500
@@ -155,8 +155,10 @@ static void pnv_smp_cpu_kill_self(void)
 		wmask = SRR1_WAKEMASK_P8;
 
 	idle_states = pnv_get_supported_cpuidle_states();
+
 	/* We don't want to take decrementer interrupts while we are offline,
-	 * so clear LPCR:PECE1. We keep PECE2 enabled.
+	 * so clear LPCR:PECE1. We keep PECE2 (and LPCR_PECE_HVEE on P9)
+	 * enabled as to let IPIs in.
 	 */
 	mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1);
 
@@ -206,8 +208,12 @@ static void pnv_smp_cpu_kill_self(void)
 		 * contains 0.
 		 */
 		if (((srr1 & wmask) == SRR1_WAKEEE) ||
+		    ((srr1 & wmask) == SRR1_WAKEHVI) ||
 		    (local_paca->irq_happened & PACA_IRQ_EE)) {
-			icp_native_flush_interrupt();
+			if (cpu_has_feature(CPU_FTR_ARCH_300))
+				icp_opal_flush_interrupt();
+			else
+				icp_native_flush_interrupt();
 		} else if ((srr1 & wmask) == SRR1_WAKEHDBELL) {
 			unsigned long msg = PPC_DBELL_TYPE(PPC_DBELL_SERVER);
 			asm volatile(PPC_MSGCLR(%0) : : "r" (msg));
@@ -221,6 +227,8 @@ static void pnv_smp_cpu_kill_self(void)
 		if (srr1 && !generic_check_cpu_restart(cpu))
 			DBG("CPU%d Unexpected exit while offline !\n", cpu);
 	}
+
+	/* Re-enable decrementer interrupts */
 	mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) | LPCR_PECE1);
 	DBG("CPU%d coming online...\n", cpu);
 }
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/powerpc/sysdev/xics/icp-opal.c linux-libre-4.10-rc8-gnu/arch/powerpc/sysdev/xics/icp-opal.c
--- linux-libre-4.10-rc7-gnu/arch/powerpc/sysdev/xics/icp-opal.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/powerpc/sysdev/xics/icp-opal.c	2017-02-12 16:03:20.000000000 -0500
@@ -120,18 +120,49 @@ static void icp_opal_cause_ipi(int cpu,
 {
 	int hw_cpu = get_hard_smp_processor_id(cpu);
 
+	kvmppc_set_host_ipi(cpu, 1);
 	opal_int_set_mfrr(hw_cpu, IPI_PRIORITY);
 }
 
 static irqreturn_t icp_opal_ipi_action(int irq, void *dev_id)
 {
-	int hw_cpu = hard_smp_processor_id();
+	int cpu = smp_processor_id();
 
-	opal_int_set_mfrr(hw_cpu, 0xff);
+	kvmppc_set_host_ipi(cpu, 0);
+	opal_int_set_mfrr(get_hard_smp_processor_id(cpu), 0xff);
 
 	return smp_ipi_demux();
 }
 
+/*
+ * Called when an interrupt is received on an off-line CPU to
+ * clear the interrupt, so that the CPU can go back to nap mode.
+ */
+void icp_opal_flush_interrupt(void)
+{
+	unsigned int xirr;
+	unsigned int vec;
+
+	do {
+		xirr = icp_opal_get_xirr();
+		vec = xirr & 0x00ffffff;
+		if (vec == XICS_IRQ_SPURIOUS)
+			break;
+		if (vec == XICS_IPI) {
+			/* Clear pending IPI */
+			int cpu = smp_processor_id();
+			kvmppc_set_host_ipi(cpu, 0);
+			opal_int_set_mfrr(get_hard_smp_processor_id(cpu), 0xff);
+		} else {
+			pr_err("XICS: hw interrupt 0x%x to offline cpu, "
+			       "disabling\n", vec);
+			xics_mask_unknown_vec(vec);
+		}
+
+		/* EOI the interrupt */
+	} while (opal_int_eoi(xirr) > 0);
+}
+
 #endif /* CONFIG_SMP */
 
 static const struct icp_ops icp_opal_ops = {
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/x86/crypto/aesni-intel_glue.c linux-libre-4.10-rc8-gnu/arch/x86/crypto/aesni-intel_glue.c
--- linux-libre-4.10-rc7-gnu/arch/x86/crypto/aesni-intel_glue.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/x86/crypto/aesni-intel_glue.c	2017-02-12 16:03:20.000000000 -0500
@@ -1085,9 +1085,9 @@ static void aesni_free_simds(void)
 		    aesni_simd_skciphers[i]; i++)
 		simd_skcipher_free(aesni_simd_skciphers[i]);
 
-	for (i = 0; i < ARRAY_SIZE(aesni_simd_skciphers2) &&
-		    aesni_simd_skciphers2[i].simd; i++)
-		simd_skcipher_free(aesni_simd_skciphers2[i].simd);
+	for (i = 0; i < ARRAY_SIZE(aesni_simd_skciphers2); i++)
+		if (aesni_simd_skciphers2[i].simd)
+			simd_skcipher_free(aesni_simd_skciphers2[i].simd);
 }
 
 static int __init aesni_init(void)
@@ -1168,7 +1168,7 @@ static int __init aesni_init(void)
 		simd = simd_skcipher_create_compat(algname, drvname, basename);
 		err = PTR_ERR(simd);
 		if (IS_ERR(simd))
-			goto unregister_simds;
+			continue;
 
 		aesni_simd_skciphers2[i].simd = simd;
 	}
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/x86/include/asm/processor.h linux-libre-4.10-rc8-gnu/arch/x86/include/asm/processor.h
--- linux-libre-4.10-rc7-gnu/arch/x86/include/asm/processor.h	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/x86/include/asm/processor.h	2017-02-12 16:03:20.000000000 -0500
@@ -104,6 +104,7 @@ struct cpuinfo_x86 {
 	__u8			x86_phys_bits;
 	/* CPUID returned core id bits: */
 	__u8			x86_coreid_bits;
+	__u8			cu_id;
 	/* Max extended CPUID function supported: */
 	__u32			extended_cpuid_level;
 	/* Maximum supported CPUID level, -1=no CPUID: */
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/x86/kernel/apic/io_apic.c linux-libre-4.10-rc8-gnu/arch/x86/kernel/apic/io_apic.c
--- linux-libre-4.10-rc7-gnu/arch/x86/kernel/apic/io_apic.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/x86/kernel/apic/io_apic.c	2017-02-12 16:03:20.000000000 -0500
@@ -1875,7 +1875,6 @@ static struct irq_chip ioapic_chip __rea
 	.irq_ack		= irq_chip_ack_parent,
 	.irq_eoi		= ioapic_ack_level,
 	.irq_set_affinity	= ioapic_set_affinity,
-	.irq_retrigger		= irq_chip_retrigger_hierarchy,
 	.flags			= IRQCHIP_SKIP_SET_WAKE,
 };
 
@@ -1887,7 +1886,6 @@ static struct irq_chip ioapic_ir_chip __
 	.irq_ack		= irq_chip_ack_parent,
 	.irq_eoi		= ioapic_ir_ack_level,
 	.irq_set_affinity	= ioapic_set_affinity,
-	.irq_retrigger		= irq_chip_retrigger_hierarchy,
 	.flags			= IRQCHIP_SKIP_SET_WAKE,
 };
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/x86/kernel/cpu/amd.c linux-libre-4.10-rc8-gnu/arch/x86/kernel/cpu/amd.c
--- linux-libre-4.10-rc7-gnu/arch/x86/kernel/cpu/amd.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/x86/kernel/cpu/amd.c	2017-02-12 16:03:20.000000000 -0500
@@ -309,8 +309,22 @@ static void amd_get_topology(struct cpui
 
 	/* get information required for multi-node processors */
 	if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
+		u32 eax, ebx, ecx, edx;
 
-		node_id = cpuid_ecx(0x8000001e) & 7;
+		cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);
+
+		node_id  = ecx & 0xff;
+		smp_num_siblings = ((ebx >> 8) & 0xff) + 1;
+
+		if (c->x86 == 0x15)
+			c->cu_id = ebx & 0xff;
+
+		if (c->x86 >= 0x17) {
+			c->cpu_core_id = ebx & 0xff;
+
+			if (smp_num_siblings > 1)
+				c->x86_max_cores /= smp_num_siblings;
+		}
 
 		/*
 		 * We may have multiple LLCs if L3 caches exist, so check if we
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/x86/kernel/cpu/common.c linux-libre-4.10-rc8-gnu/arch/x86/kernel/cpu/common.c
--- linux-libre-4.10-rc7-gnu/arch/x86/kernel/cpu/common.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/x86/kernel/cpu/common.c	2017-02-12 16:03:20.000000000 -0500
@@ -1015,6 +1015,7 @@ static void identify_cpu(struct cpuinfo_
 	c->x86_model_id[0] = '\0';  /* Unset */
 	c->x86_max_cores = 1;
 	c->x86_coreid_bits = 0;
+	c->cu_id = 0xff;
 #ifdef CONFIG_X86_64
 	c->x86_clflush_size = 64;
 	c->x86_phys_bits = 36;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/x86/kernel/smpboot.c linux-libre-4.10-rc8-gnu/arch/x86/kernel/smpboot.c
--- linux-libre-4.10-rc7-gnu/arch/x86/kernel/smpboot.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/x86/kernel/smpboot.c	2017-02-12 16:03:20.000000000 -0500
@@ -433,9 +433,15 @@ static bool match_smt(struct cpuinfo_x86
 		int cpu1 = c->cpu_index, cpu2 = o->cpu_index;
 
 		if (c->phys_proc_id == o->phys_proc_id &&
-		    per_cpu(cpu_llc_id, cpu1) == per_cpu(cpu_llc_id, cpu2) &&
-		    c->cpu_core_id == o->cpu_core_id)
-			return topology_sane(c, o, "smt");
+		    per_cpu(cpu_llc_id, cpu1) == per_cpu(cpu_llc_id, cpu2)) {
+			if (c->cpu_core_id == o->cpu_core_id)
+				return topology_sane(c, o, "smt");
+
+			if ((c->cu_id != 0xff) &&
+			    (o->cu_id != 0xff) &&
+			    (c->cu_id == o->cu_id))
+				return topology_sane(c, o, "smt");
+		}
 
 	} else if (c->phys_proc_id == o->phys_proc_id &&
 		   c->cpu_core_id == o->cpu_core_id) {
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/x86/kernel/tsc.c linux-libre-4.10-rc8-gnu/arch/x86/kernel/tsc.c
--- linux-libre-4.10-rc7-gnu/arch/x86/kernel/tsc.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/x86/kernel/tsc.c	2017-02-12 16:03:20.000000000 -0500
@@ -1356,6 +1356,9 @@ void __init tsc_init(void)
 		(unsigned long)cpu_khz / 1000,
 		(unsigned long)cpu_khz % 1000);
 
+	/* Sanitize TSC ADJUST before cyc2ns gets initialized */
+	tsc_store_and_check_tsc_adjust(true);
+
 	/*
 	 * Secondary CPUs do not run through tsc_init(), so set up
 	 * all the scale factors for all CPUs, assuming the same
@@ -1386,8 +1389,6 @@ void __init tsc_init(void)
 
 	if (unsynchronized_tsc())
 		mark_tsc_unstable("TSCs unsynchronized");
-	else
-		tsc_store_and_check_tsc_adjust(true);
 
 	check_system_tsc_reliable();
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/x86/kernel/tsc_sync.c linux-libre-4.10-rc8-gnu/arch/x86/kernel/tsc_sync.c
--- linux-libre-4.10-rc7-gnu/arch/x86/kernel/tsc_sync.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/x86/kernel/tsc_sync.c	2017-02-12 16:03:20.000000000 -0500
@@ -286,13 +286,6 @@ void check_tsc_sync_source(int cpu)
 	if (unsynchronized_tsc())
 		return;
 
-	if (tsc_clocksource_reliable) {
-		if (cpu == (nr_cpu_ids-1) || system_state != SYSTEM_BOOTING)
-			pr_info(
-			"Skipped synchronization checks as TSC is reliable.\n");
-		return;
-	}
-
 	/*
 	 * Set the maximum number of test runs to
 	 *  1 if the CPU does not provide the TSC_ADJUST MSR
@@ -380,14 +373,19 @@ void check_tsc_sync_target(void)
 	int cpus = 2;
 
 	/* Also aborts if there is no TSC. */
-	if (unsynchronized_tsc() || tsc_clocksource_reliable)
+	if (unsynchronized_tsc())
 		return;
 
 	/*
 	 * Store, verify and sanitize the TSC adjust register. If
 	 * successful skip the test.
+	 *
+	 * The test is also skipped when the TSC is marked reliable. This
+	 * is true for SoCs which have no fallback clocksource. On these
+	 * SoCs the TSC is frequency synchronized, but still the TSC ADJUST
+	 * register might have been wreckaged by the BIOS..
 	 */
-	if (tsc_store_and_check_tsc_adjust(false)) {
+	if (tsc_store_and_check_tsc_adjust(false) || tsc_clocksource_reliable) {
 		atomic_inc(&skip_test);
 		return;
 	}
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/arch/x86/mm/dump_pagetables.c linux-libre-4.10-rc8-gnu/arch/x86/mm/dump_pagetables.c
--- linux-libre-4.10-rc7-gnu/arch/x86/mm/dump_pagetables.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/arch/x86/mm/dump_pagetables.c	2017-02-12 16:03:20.000000000 -0500
@@ -15,6 +15,7 @@
 #include <linux/debugfs.h>
 #include <linux/mm.h>
 #include <linux/init.h>
+#include <linux/sched.h>
 #include <linux/seq_file.h>
 
 #include <asm/pgtable.h>
@@ -406,6 +407,7 @@ static void ptdump_walk_pgd_level_core(s
 		} else
 			note_page(m, &st, __pgprot(0), 1);
 
+		cond_resched();
 		start++;
 	}
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/block/blk-lib.c linux-libre-4.10-rc8-gnu/block/blk-lib.c
--- linux-libre-4.10-rc7-gnu/block/blk-lib.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/block/blk-lib.c	2017-02-12 16:03:20.000000000 -0500
@@ -306,11 +306,6 @@ int __blkdev_issue_zeroout(struct block_
 	if (ret == 0 || (ret && ret != -EOPNOTSUPP))
 		goto out;
 
-	ret = __blkdev_issue_write_same(bdev, sector, nr_sects, gfp_mask,
-			ZERO_PAGE(0), biop);
-	if (ret == 0 || (ret && ret != -EOPNOTSUPP))
-		goto out;
-
 	ret = 0;
 	while (nr_sects != 0) {
 		bio = next_bio(bio, min(nr_sects, (sector_t)BIO_MAX_PAGES),
@@ -369,6 +364,10 @@ int blkdev_issue_zeroout(struct block_de
 			return 0;
 	}
 
+	if (!blkdev_issue_write_same(bdev, sector, nr_sects, gfp_mask,
+			ZERO_PAGE(0)))
+		return 0;
+
 	blk_start_plug(&plug);
 	ret = __blkdev_issue_zeroout(bdev, sector, nr_sects, gfp_mask,
 			&bio, discard);
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/crypto/algif_aead.c linux-libre-4.10-rc8-gnu/crypto/algif_aead.c
--- linux-libre-4.10-rc7-gnu/crypto/algif_aead.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/crypto/algif_aead.c	2017-02-12 16:03:20.000000000 -0500
@@ -661,9 +661,9 @@ static int aead_recvmsg_sync(struct sock
 unlock:
 	list_for_each_entry_safe(rsgl, tmp, &ctx->list, list) {
 		af_alg_free_sg(&rsgl->sgl);
+		list_del(&rsgl->list);
 		if (rsgl != &ctx->first_rsgl)
 			sock_kfree_s(sk, rsgl, sizeof(*rsgl));
-		list_del(&rsgl->list);
 	}
 	INIT_LIST_HEAD(&ctx->list);
 	aead_wmem_wakeup(sk);
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/Documentation/media/uapi/cec/cec-func-close.rst linux-libre-4.10-rc8-gnu/Documentation/media/uapi/cec/cec-func-close.rst
--- linux-libre-4.10-rc7-gnu/Documentation/media/uapi/cec/cec-func-close.rst	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/Documentation/media/uapi/cec/cec-func-close.rst	2017-02-12 16:03:20.000000000 -0500
@@ -33,11 +33,6 @@ Arguments
 Description
 ===========
 
-.. note::
-
-   This documents the proposed CEC API. This API is not yet finalized
-   and is currently only available as a staging kernel module.
-
 Closes the cec device. Resources associated with the file descriptor are
 freed. The device configuration remain unchanged.
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/Documentation/media/uapi/cec/cec-func-ioctl.rst linux-libre-4.10-rc8-gnu/Documentation/media/uapi/cec/cec-func-ioctl.rst
--- linux-libre-4.10-rc7-gnu/Documentation/media/uapi/cec/cec-func-ioctl.rst	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/Documentation/media/uapi/cec/cec-func-ioctl.rst	2017-02-12 16:03:20.000000000 -0500
@@ -39,11 +39,6 @@ Arguments
 Description
 ===========
 
-.. note::
-
-   This documents the proposed CEC API. This API is not yet finalized
-   and is currently only available as a staging kernel module.
-
 The :c:func:`ioctl()` function manipulates cec device parameters. The
 argument ``fd`` must be an open file descriptor.
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/Documentation/media/uapi/cec/cec-func-open.rst linux-libre-4.10-rc8-gnu/Documentation/media/uapi/cec/cec-func-open.rst
--- linux-libre-4.10-rc7-gnu/Documentation/media/uapi/cec/cec-func-open.rst	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/Documentation/media/uapi/cec/cec-func-open.rst	2017-02-12 16:03:20.000000000 -0500
@@ -46,11 +46,6 @@ Arguments
 Description
 ===========
 
-.. note::
-
-   This documents the proposed CEC API. This API is not yet finalized
-   and is currently only available as a staging kernel module.
-
 To open a cec device applications call :c:func:`open()` with the
 desired device name. The function has no side effects; the device
 configuration remain unchanged.
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/Documentation/media/uapi/cec/cec-func-poll.rst linux-libre-4.10-rc8-gnu/Documentation/media/uapi/cec/cec-func-poll.rst
--- linux-libre-4.10-rc7-gnu/Documentation/media/uapi/cec/cec-func-poll.rst	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/Documentation/media/uapi/cec/cec-func-poll.rst	2017-02-12 16:03:20.000000000 -0500
@@ -39,11 +39,6 @@ Arguments
 Description
 ===========
 
-.. note::
-
-   This documents the proposed CEC API. This API is not yet finalized
-   and is currently only available as a staging kernel module.
-
 With the :c:func:`poll()` function applications can wait for CEC
 events.
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/Documentation/media/uapi/cec/cec-intro.rst linux-libre-4.10-rc8-gnu/Documentation/media/uapi/cec/cec-intro.rst
--- linux-libre-4.10-rc7-gnu/Documentation/media/uapi/cec/cec-intro.rst	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/Documentation/media/uapi/cec/cec-intro.rst	2017-02-12 16:03:20.000000000 -0500
@@ -3,11 +3,6 @@
 Introduction
 ============
 
-.. note::
-
-   This documents the proposed CEC API. This API is not yet finalized
-   and is currently only available as a staging kernel module.
-
 HDMI connectors provide a single pin for use by the Consumer Electronics
 Control protocol. This protocol allows different devices connected by an
 HDMI cable to communicate. The protocol for CEC version 1.4 is defined
@@ -31,3 +26,15 @@ control just the CEC pin.
 Drivers that support CEC will create a CEC device node (/dev/cecX) to
 give userspace access to the CEC adapter. The
 :ref:`CEC_ADAP_G_CAPS` ioctl will tell userspace what it is allowed to do.
+
+In order to check the support and test it, it is suggested to download
+the `v4l-utils <https://git.linuxtv.org/v4l-utils.git/>`_ package. It
+provides three tools to handle CEC:
+
+- cec-ctl: the Swiss army knife of CEC. Allows you to configure, transmit
+  and monitor CEC messages.
+
+- cec-compliance: does a CEC compliance test of a remote CEC device to
+  determine how compliant the CEC implementation is.
+
+- cec-follower: emulates a CEC follower.
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst linux-libre-4.10-rc8-gnu/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst
--- linux-libre-4.10-rc7-gnu/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst	2017-02-12 16:03:20.000000000 -0500
@@ -29,11 +29,6 @@ Arguments
 Description
 ===========
 
-.. note::
-
-   This documents the proposed CEC API. This API is not yet finalized
-   and is currently only available as a staging kernel module.
-
 All cec devices must support :ref:`ioctl CEC_ADAP_G_CAPS <CEC_ADAP_G_CAPS>`. To query
 device information, applications call the ioctl with a pointer to a
 struct :c:type:`cec_caps`. The driver fills the structure and
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst linux-libre-4.10-rc8-gnu/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst
--- linux-libre-4.10-rc7-gnu/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst	2017-02-12 16:03:20.000000000 -0500
@@ -35,11 +35,6 @@ Arguments
 Description
 ===========
 
-.. note::
-
-   This documents the proposed CEC API. This API is not yet finalized
-   and is currently only available as a staging kernel module.
-
 To query the current CEC logical addresses, applications call
 :ref:`ioctl CEC_ADAP_G_LOG_ADDRS <CEC_ADAP_G_LOG_ADDRS>` with a pointer to a
 struct :c:type:`cec_log_addrs` where the driver stores the logical addresses.
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/Documentation/media/uapi/cec/cec-ioc-adap-g-phys-addr.rst linux-libre-4.10-rc8-gnu/Documentation/media/uapi/cec/cec-ioc-adap-g-phys-addr.rst
--- linux-libre-4.10-rc7-gnu/Documentation/media/uapi/cec/cec-ioc-adap-g-phys-addr.rst	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/Documentation/media/uapi/cec/cec-ioc-adap-g-phys-addr.rst	2017-02-12 16:03:20.000000000 -0500
@@ -35,11 +35,6 @@ Arguments
 Description
 ===========
 
-.. note::
-
-   This documents the proposed CEC API. This API is not yet finalized
-   and is currently only available as a staging kernel module.
-
 To query the current physical address applications call
 :ref:`ioctl CEC_ADAP_G_PHYS_ADDR <CEC_ADAP_G_PHYS_ADDR>` with a pointer to a __u16 where the
 driver stores the physical address.
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/Documentation/media/uapi/cec/cec-ioc-dqevent.rst linux-libre-4.10-rc8-gnu/Documentation/media/uapi/cec/cec-ioc-dqevent.rst
--- linux-libre-4.10-rc7-gnu/Documentation/media/uapi/cec/cec-ioc-dqevent.rst	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/Documentation/media/uapi/cec/cec-ioc-dqevent.rst	2017-02-12 16:03:20.000000000 -0500
@@ -30,11 +30,6 @@ Arguments
 Description
 ===========
 
-.. note::
-
-   This documents the proposed CEC API. This API is not yet finalized
-   and is currently only available as a staging kernel module.
-
 CEC devices can send asynchronous events. These can be retrieved by
 calling :c:func:`CEC_DQEVENT`. If the file descriptor is in
 non-blocking mode and no event is pending, then it will return -1 and
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/Documentation/media/uapi/cec/cec-ioc-g-mode.rst linux-libre-4.10-rc8-gnu/Documentation/media/uapi/cec/cec-ioc-g-mode.rst
--- linux-libre-4.10-rc7-gnu/Documentation/media/uapi/cec/cec-ioc-g-mode.rst	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/Documentation/media/uapi/cec/cec-ioc-g-mode.rst	2017-02-12 16:03:20.000000000 -0500
@@ -31,11 +31,6 @@ Arguments
 Description
 ===========
 
-.. note::
-
-   This documents the proposed CEC API. This API is not yet finalized
-   and is currently only available as a staging kernel module.
-
 By default any filehandle can use :ref:`CEC_TRANSMIT`, but in order to prevent
 applications from stepping on each others toes it must be possible to
 obtain exclusive access to the CEC adapter. This ioctl sets the
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/Documentation/media/uapi/cec/cec-ioc-receive.rst linux-libre-4.10-rc8-gnu/Documentation/media/uapi/cec/cec-ioc-receive.rst
--- linux-libre-4.10-rc7-gnu/Documentation/media/uapi/cec/cec-ioc-receive.rst	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/Documentation/media/uapi/cec/cec-ioc-receive.rst	2017-02-12 16:03:20.000000000 -0500
@@ -34,11 +34,6 @@ Arguments
 Description
 ===========
 
-.. note::
-
-   This documents the proposed CEC API. This API is not yet finalized
-   and is currently only available as a staging kernel module.
-
 To receive a CEC message the application has to fill in the
 ``timeout`` field of struct :c:type:`cec_msg` and pass it to
 :ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>`.
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/acpi/nfit/core.c linux-libre-4.10-rc8-gnu/drivers/acpi/nfit/core.c
--- linux-libre-4.10-rc7-gnu/drivers/acpi/nfit/core.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/acpi/nfit/core.c	2017-02-12 16:03:20.000000000 -0500
@@ -2704,6 +2704,7 @@ static int acpi_nfit_flush_probe(struct
 	struct acpi_nfit_desc *acpi_desc = to_acpi_nfit_desc(nd_desc);
 	struct device *dev = acpi_desc->dev;
 	struct acpi_nfit_flush_work flush;
+	int rc;
 
 	/* bounce the device lock to flush acpi_nfit_add / acpi_nfit_notify */
 	device_lock(dev);
@@ -2716,7 +2717,10 @@ static int acpi_nfit_flush_probe(struct
 	INIT_WORK_ONSTACK(&flush.work, flush_probe);
 	COMPLETION_INITIALIZER_ONSTACK(flush.cmp);
 	queue_work(nfit_wq, &flush.work);
-	return wait_for_completion_interruptible(&flush.cmp);
+
+	rc = wait_for_completion_interruptible(&flush.cmp);
+	cancel_work_sync(&flush.work);
+	return rc;
 }
 
 static int acpi_nfit_clear_to_send(struct nvdimm_bus_descriptor *nd_desc,
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/base/power/runtime.c linux-libre-4.10-rc8-gnu/drivers/base/power/runtime.c
--- linux-libre-4.10-rc7-gnu/drivers/base/power/runtime.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/base/power/runtime.c	2017-02-12 16:03:20.000000000 -0500
@@ -966,13 +966,13 @@ int __pm_runtime_idle(struct device *dev
 	unsigned long flags;
 	int retval;
 
-	might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe);
-
 	if (rpmflags & RPM_GET_PUT) {
 		if (!atomic_dec_and_test(&dev->power.usage_count))
 			return 0;
 	}
 
+	might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe);
+
 	spin_lock_irqsave(&dev->power.lock, flags);
 	retval = rpm_idle(dev, rpmflags);
 	spin_unlock_irqrestore(&dev->power.lock, flags);
@@ -998,13 +998,13 @@ int __pm_runtime_suspend(struct device *
 	unsigned long flags;
 	int retval;
 
-	might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe);
-
 	if (rpmflags & RPM_GET_PUT) {
 		if (!atomic_dec_and_test(&dev->power.usage_count))
 			return 0;
 	}
 
+	might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe);
+
 	spin_lock_irqsave(&dev->power.lock, flags);
 	retval = rpm_suspend(dev, rpmflags);
 	spin_unlock_irqrestore(&dev->power.lock, flags);
@@ -1029,7 +1029,8 @@ int __pm_runtime_resume(struct device *d
 	unsigned long flags;
 	int retval;
 
-	might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe);
+	might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe &&
+			dev->power.runtime_status != RPM_ACTIVE);
 
 	if (rpmflags & RPM_GET_PUT)
 		atomic_inc(&dev->power.usage_count);
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/char/hw_random/core.c linux-libre-4.10-rc8-gnu/drivers/char/hw_random/core.c
--- linux-libre-4.10-rc7-gnu/drivers/char/hw_random/core.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/char/hw_random/core.c	2017-02-12 16:03:20.000000000 -0500
@@ -92,7 +92,6 @@ static void add_early_randomness(struct
 	mutex_unlock(&reading_mutex);
 	if (bytes_read > 0)
 		add_device_randomness(rng_buffer, bytes_read);
-	memset(rng_buffer, 0, size);
 }
 
 static inline void cleanup_rng(struct kref *kref)
@@ -288,7 +287,6 @@ static ssize_t rng_dev_read(struct file
 		}
 	}
 out:
-	memset(rng_buffer, 0, rng_buffer_size());
 	return ret ? : err;
 
 out_unlock_reading:
@@ -427,7 +425,6 @@ static int hwrng_fillfn(void *unused)
 		/* Outside lock, sure, but y'know: randomness. */
 		add_hwgenerator_randomness((void *)rng_fillbuf, rc,
 					   rc * current_quality * 8 >> 10);
-		memset(rng_fillbuf, 0, rng_buffer_size());
 	}
 	hwrng_fill = NULL;
 	return 0;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/cpufreq/brcmstb-avs-cpufreq.c linux-libre-4.10-rc8-gnu/drivers/cpufreq/brcmstb-avs-cpufreq.c
--- linux-libre-4.10-rc7-gnu/drivers/cpufreq/brcmstb-avs-cpufreq.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/cpufreq/brcmstb-avs-cpufreq.c	2017-02-12 16:03:20.000000000 -0500
@@ -784,8 +784,19 @@ static int brcm_avs_target_index(struct
 static int brcm_avs_suspend(struct cpufreq_policy *policy)
 {
 	struct private_data *priv = policy->driver_data;
+	int ret;
 
-	return brcm_avs_get_pmap(priv, &priv->pmap);
+	ret = brcm_avs_get_pmap(priv, &priv->pmap);
+	if (ret)
+		return ret;
+
+	/*
+	 * We can't use the P-state returned by brcm_avs_get_pmap(), since
+	 * that's the initial P-state from when the P-map was downloaded to the
+	 * AVS co-processor, not necessarily the P-state we are running at now.
+	 * So, we get the current P-state explicitly.
+	 */
+	return brcm_avs_get_pstate(priv, &priv->pmap.state);
 }
 
 static int brcm_avs_resume(struct cpufreq_policy *policy)
@@ -954,9 +965,9 @@ static ssize_t show_brcm_avs_pmap(struct
 	brcm_avs_parse_p1(pmap.p1, &mdiv_p0, &pdiv, &ndiv);
 	brcm_avs_parse_p2(pmap.p2, &mdiv_p1, &mdiv_p2, &mdiv_p3, &mdiv_p4);
 
-	return sprintf(buf, "0x%08x 0x%08x %u %u %u %u %u %u %u\n",
+	return sprintf(buf, "0x%08x 0x%08x %u %u %u %u %u %u %u %u %u\n",
 		pmap.p1, pmap.p2, ndiv, pdiv, mdiv_p0, mdiv_p1, mdiv_p2,
-		mdiv_p3, mdiv_p4);
+		mdiv_p3, mdiv_p4, pmap.mode, pmap.state);
 }
 
 static ssize_t show_brcm_avs_voltage(struct cpufreq_policy *policy, char *buf)
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/cpufreq/intel_pstate.c linux-libre-4.10-rc8-gnu/drivers/cpufreq/intel_pstate.c
--- linux-libre-4.10-rc7-gnu/drivers/cpufreq/intel_pstate.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/cpufreq/intel_pstate.c	2017-02-12 16:03:20.000000000 -0500
@@ -1235,6 +1235,25 @@ static void intel_pstate_hwp_enable(stru
 		cpudata->epp_default = intel_pstate_get_epp(cpudata, 0);
 }
 
+#define MSR_IA32_POWER_CTL_BIT_EE	19
+
+/* Disable energy efficiency optimization */
+static void intel_pstate_disable_ee(int cpu)
+{
+	u64 power_ctl;
+	int ret;
+
+	ret = rdmsrl_on_cpu(cpu, MSR_IA32_POWER_CTL, &power_ctl);
+	if (ret)
+		return;
+
+	if (!(power_ctl & BIT(MSR_IA32_POWER_CTL_BIT_EE))) {
+		pr_info("Disabling energy efficiency optimization\n");
+		power_ctl |= BIT(MSR_IA32_POWER_CTL_BIT_EE);
+		wrmsrl_on_cpu(cpu, MSR_IA32_POWER_CTL, power_ctl);
+	}
+}
+
 static int atom_get_min_pstate(void)
 {
 	u64 value;
@@ -1845,6 +1864,11 @@ static const struct x86_cpu_id intel_pst
 	{}
 };
 
+static const struct x86_cpu_id intel_pstate_cpu_ee_disable_ids[] = {
+	ICPU(INTEL_FAM6_KABYLAKE_DESKTOP, core_params),
+	{}
+};
+
 static int intel_pstate_init_cpu(unsigned int cpunum)
 {
 	struct cpudata *cpu;
@@ -1875,6 +1899,12 @@ static int intel_pstate_init_cpu(unsigne
 	cpu->cpu = cpunum;
 
 	if (hwp_active) {
+		const struct x86_cpu_id *id;
+
+		id = x86_match_cpu(intel_pstate_cpu_ee_disable_ids);
+		if (id)
+			intel_pstate_disable_ee(cpunum);
+
 		intel_pstate_hwp_enable(cpu);
 		pid_params.sample_rate_ms = 50;
 		pid_params.sample_rate_ns = 50 * NSEC_PER_MSEC;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/crypto/ccp/ccp-dev.h linux-libre-4.10-rc8-gnu/drivers/crypto/ccp/ccp-dev.h
--- linux-libre-4.10-rc7-gnu/drivers/crypto/ccp/ccp-dev.h	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/crypto/ccp/ccp-dev.h	2017-02-12 16:03:20.000000000 -0500
@@ -238,6 +238,7 @@ struct ccp_dma_chan {
 	struct ccp_device *ccp;
 
 	spinlock_t lock;
+	struct list_head created;
 	struct list_head pending;
 	struct list_head active;
 	struct list_head complete;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/crypto/ccp/ccp-dev-v5.c linux-libre-4.10-rc8-gnu/drivers/crypto/ccp/ccp-dev-v5.c
--- linux-libre-4.10-rc7-gnu/drivers/crypto/ccp/ccp-dev-v5.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/crypto/ccp/ccp-dev-v5.c	2017-02-12 16:03:20.000000000 -0500
@@ -959,7 +959,7 @@ static irqreturn_t ccp5_irq_handler(int
 static void ccp5_config(struct ccp_device *ccp)
 {
 	/* Public side */
-	iowrite32(0x00001249, ccp->io_regs + CMD5_REQID_CONFIG_OFFSET);
+	iowrite32(0x0, ccp->io_regs + CMD5_REQID_CONFIG_OFFSET);
 }
 
 static void ccp5other_config(struct ccp_device *ccp)
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/crypto/ccp/ccp-dmaengine.c linux-libre-4.10-rc8-gnu/drivers/crypto/ccp/ccp-dmaengine.c
--- linux-libre-4.10-rc7-gnu/drivers/crypto/ccp/ccp-dmaengine.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/crypto/ccp/ccp-dmaengine.c	2017-02-12 16:03:20.000000000 -0500
@@ -63,6 +63,7 @@ static void ccp_free_chan_resources(stru
 	ccp_free_desc_resources(chan->ccp, &chan->complete);
 	ccp_free_desc_resources(chan->ccp, &chan->active);
 	ccp_free_desc_resources(chan->ccp, &chan->pending);
+	ccp_free_desc_resources(chan->ccp, &chan->created);
 
 	spin_unlock_irqrestore(&chan->lock, flags);
 }
@@ -273,6 +274,7 @@ static dma_cookie_t ccp_tx_submit(struct
 	spin_lock_irqsave(&chan->lock, flags);
 
 	cookie = dma_cookie_assign(tx_desc);
+	list_del(&desc->entry);
 	list_add_tail(&desc->entry, &chan->pending);
 
 	spin_unlock_irqrestore(&chan->lock, flags);
@@ -426,7 +428,7 @@ static struct ccp_dma_desc *ccp_create_d
 
 	spin_lock_irqsave(&chan->lock, sflags);
 
-	list_add_tail(&desc->entry, &chan->pending);
+	list_add_tail(&desc->entry, &chan->created);
 
 	spin_unlock_irqrestore(&chan->lock, sflags);
 
@@ -610,6 +612,7 @@ static int ccp_terminate_all(struct dma_
 	/*TODO: Purge the complete list? */
 	ccp_free_desc_resources(chan->ccp, &chan->active);
 	ccp_free_desc_resources(chan->ccp, &chan->pending);
+	ccp_free_desc_resources(chan->ccp, &chan->created);
 
 	spin_unlock_irqrestore(&chan->lock, flags);
 
@@ -679,6 +682,7 @@ int ccp_dmaengine_register(struct ccp_de
 		chan->ccp = ccp;
 
 		spin_lock_init(&chan->lock);
+		INIT_LIST_HEAD(&chan->created);
 		INIT_LIST_HEAD(&chan->pending);
 		INIT_LIST_HEAD(&chan->active);
 		INIT_LIST_HEAD(&chan->complete);
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/crypto/chelsio/chcr_algo.c linux-libre-4.10-rc8-gnu/drivers/crypto/chelsio/chcr_algo.c
--- linux-libre-4.10-rc7-gnu/drivers/crypto/chelsio/chcr_algo.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/crypto/chelsio/chcr_algo.c	2017-02-12 16:03:20.000000000 -0500
@@ -158,7 +158,7 @@ int chcr_handle_resp(struct crypto_async
 	case CRYPTO_ALG_TYPE_AEAD:
 		ctx_req.req.aead_req = (struct aead_request *)req;
 		ctx_req.ctx.reqctx = aead_request_ctx(ctx_req.req.aead_req);
-		dma_unmap_sg(&u_ctx->lldi.pdev->dev, ctx_req.req.aead_req->dst,
+		dma_unmap_sg(&u_ctx->lldi.pdev->dev, ctx_req.ctx.reqctx->dst,
 			     ctx_req.ctx.reqctx->dst_nents, DMA_FROM_DEVICE);
 		if (ctx_req.ctx.reqctx->skb) {
 			kfree_skb(ctx_req.ctx.reqctx->skb);
@@ -1362,8 +1362,7 @@ static struct sk_buff *create_authenc_wr
 	struct chcr_wr *chcr_req;
 	struct cpl_rx_phys_dsgl *phys_cpl;
 	struct phys_sge_parm sg_param;
-	struct scatterlist *src, *dst;
-	struct scatterlist src_sg[2], dst_sg[2];
+	struct scatterlist *src;
 	unsigned int frags = 0, transhdr_len;
 	unsigned int ivsize = crypto_aead_ivsize(tfm), dst_size = 0;
 	unsigned int   kctx_len = 0;
@@ -1383,19 +1382,21 @@ static struct sk_buff *create_authenc_wr
 
 	if (sg_nents_for_len(req->src, req->assoclen + req->cryptlen) < 0)
 		goto err;
-	src = scatterwalk_ffwd(src_sg, req->src, req->assoclen);
-	dst = src;
+	src = scatterwalk_ffwd(reqctx->srcffwd, req->src, req->assoclen);
+	reqctx->dst = src;
+
 	if (req->src != req->dst) {
 		err = chcr_copy_assoc(req, aeadctx);
 		if (err)
 			return ERR_PTR(err);
-		dst = scatterwalk_ffwd(dst_sg, req->dst, req->assoclen);
+		reqctx->dst = scatterwalk_ffwd(reqctx->dstffwd, req->dst,
+					       req->assoclen);
 	}
 	if (get_aead_subtype(tfm) == CRYPTO_ALG_SUB_TYPE_AEAD_NULL) {
 		null = 1;
 		assoclen = 0;
 	}
-	reqctx->dst_nents = sg_nents_for_len(dst, req->cryptlen +
+	reqctx->dst_nents = sg_nents_for_len(reqctx->dst, req->cryptlen +
 					     (op_type ? -authsize : authsize));
 	if (reqctx->dst_nents <= 0) {
 		pr_err("AUTHENC:Invalid Destination sg entries\n");
@@ -1460,7 +1461,7 @@ static struct sk_buff *create_authenc_wr
 	sg_param.obsize = req->cryptlen + (op_type ? -authsize : authsize);
 	sg_param.qid = qid;
 	sg_param.align = 0;
-	if (map_writesg_phys_cpl(&u_ctx->lldi.pdev->dev, phys_cpl, dst,
+	if (map_writesg_phys_cpl(&u_ctx->lldi.pdev->dev, phys_cpl, reqctx->dst,
 				  &sg_param))
 		goto dstmap_fail;
 
@@ -1711,8 +1712,7 @@ static struct sk_buff *create_aead_ccm_w
 	struct chcr_wr *chcr_req;
 	struct cpl_rx_phys_dsgl *phys_cpl;
 	struct phys_sge_parm sg_param;
-	struct scatterlist *src, *dst;
-	struct scatterlist src_sg[2], dst_sg[2];
+	struct scatterlist *src;
 	unsigned int frags = 0, transhdr_len, ivsize = AES_BLOCK_SIZE;
 	unsigned int dst_size = 0, kctx_len;
 	unsigned int sub_type;
@@ -1728,17 +1728,19 @@ static struct sk_buff *create_aead_ccm_w
 	if (sg_nents_for_len(req->src, req->assoclen + req->cryptlen) < 0)
 		goto err;
 	sub_type = get_aead_subtype(tfm);
-	src = scatterwalk_ffwd(src_sg, req->src, req->assoclen);
-	dst = src;
+	src = scatterwalk_ffwd(reqctx->srcffwd, req->src, req->assoclen);
+	reqctx->dst = src;
+
 	if (req->src != req->dst) {
 		err = chcr_copy_assoc(req, aeadctx);
 		if (err) {
 			pr_err("AAD copy to destination buffer fails\n");
 			return ERR_PTR(err);
 		}
-		dst = scatterwalk_ffwd(dst_sg, req->dst, req->assoclen);
+		reqctx->dst = scatterwalk_ffwd(reqctx->dstffwd, req->dst,
+					       req->assoclen);
 	}
-	reqctx->dst_nents = sg_nents_for_len(dst, req->cryptlen +
+	reqctx->dst_nents = sg_nents_for_len(reqctx->dst, req->cryptlen +
 					     (op_type ? -authsize : authsize));
 	if (reqctx->dst_nents <= 0) {
 		pr_err("CCM:Invalid Destination sg entries\n");
@@ -1777,7 +1779,7 @@ static struct sk_buff *create_aead_ccm_w
 	sg_param.obsize = req->cryptlen + (op_type ? -authsize : authsize);
 	sg_param.qid = qid;
 	sg_param.align = 0;
-	if (map_writesg_phys_cpl(&u_ctx->lldi.pdev->dev, phys_cpl, dst,
+	if (map_writesg_phys_cpl(&u_ctx->lldi.pdev->dev, phys_cpl, reqctx->dst,
 				  &sg_param))
 		goto dstmap_fail;
 
@@ -1809,8 +1811,7 @@ static struct sk_buff *create_gcm_wr(str
 	struct chcr_wr *chcr_req;
 	struct cpl_rx_phys_dsgl *phys_cpl;
 	struct phys_sge_parm sg_param;
-	struct scatterlist *src, *dst;
-	struct scatterlist src_sg[2], dst_sg[2];
+	struct scatterlist *src;
 	unsigned int frags = 0, transhdr_len;
 	unsigned int ivsize = AES_BLOCK_SIZE;
 	unsigned int dst_size = 0, kctx_len;
@@ -1832,13 +1833,14 @@ static struct sk_buff *create_gcm_wr(str
 	if (sg_nents_for_len(req->src, req->assoclen + req->cryptlen) < 0)
 		goto err;
 
-	src = scatterwalk_ffwd(src_sg, req->src, req->assoclen);
-	dst = src;
+	src = scatterwalk_ffwd(reqctx->srcffwd, req->src, req->assoclen);
+	reqctx->dst = src;
 	if (req->src != req->dst) {
 		err = chcr_copy_assoc(req, aeadctx);
 		if (err)
 			return	ERR_PTR(err);
-		dst = scatterwalk_ffwd(dst_sg, req->dst, req->assoclen);
+		reqctx->dst = scatterwalk_ffwd(reqctx->dstffwd, req->dst,
+					       req->assoclen);
 	}
 
 	if (!req->cryptlen)
@@ -1848,7 +1850,7 @@ static struct sk_buff *create_gcm_wr(str
 		crypt_len = AES_BLOCK_SIZE;
 	else
 		crypt_len = req->cryptlen;
-	reqctx->dst_nents = sg_nents_for_len(dst, req->cryptlen +
+	reqctx->dst_nents = sg_nents_for_len(reqctx->dst, req->cryptlen +
 					     (op_type ? -authsize : authsize));
 	if (reqctx->dst_nents <= 0) {
 		pr_err("GCM:Invalid Destination sg entries\n");
@@ -1923,7 +1925,7 @@ static struct sk_buff *create_gcm_wr(str
 	sg_param.obsize = req->cryptlen + (op_type ? -authsize : authsize);
 	sg_param.qid = qid;
 	sg_param.align = 0;
-	if (map_writesg_phys_cpl(&u_ctx->lldi.pdev->dev, phys_cpl, dst,
+	if (map_writesg_phys_cpl(&u_ctx->lldi.pdev->dev, phys_cpl, reqctx->dst,
 				  &sg_param))
 		goto dstmap_fail;
 
@@ -1937,7 +1939,8 @@ static struct sk_buff *create_gcm_wr(str
 		write_sg_to_skb(skb, &frags, src, req->cryptlen);
 	} else {
 		aes_gcm_empty_pld_pad(req->dst, authsize - 1);
-		write_sg_to_skb(skb, &frags, dst, crypt_len);
+		write_sg_to_skb(skb, &frags, reqctx->dst, crypt_len);
+
 	}
 
 	create_wreq(ctx, chcr_req, req, skb, kctx_len, size, 1,
@@ -2189,8 +2192,8 @@ static int chcr_gcm_setkey(struct crypto
 	unsigned int ck_size;
 	int ret = 0, key_ctx_size = 0;
 
-	if (get_aead_subtype(aead) ==
-	    CRYPTO_ALG_SUB_TYPE_AEAD_RFC4106) {
+	if (get_aead_subtype(aead) == CRYPTO_ALG_SUB_TYPE_AEAD_RFC4106 &&
+	    keylen > 3) {
 		keylen -= 4;  /* nonce/salt is present in the last 4 bytes */
 		memcpy(aeadctx->salt, key + keylen, 4);
 	}
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/crypto/chelsio/chcr_core.c linux-libre-4.10-rc8-gnu/drivers/crypto/chelsio/chcr_core.c
--- linux-libre-4.10-rc7-gnu/drivers/crypto/chelsio/chcr_core.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/crypto/chelsio/chcr_core.c	2017-02-12 16:03:20.000000000 -0500
@@ -52,6 +52,7 @@ static struct cxgb4_uld_info chcr_uld_in
 int assign_chcr_device(struct chcr_dev **dev)
 {
 	struct uld_ctx *u_ctx;
+	int ret = -ENXIO;
 
 	/*
 	 * Which device to use if multiple devices are available TODO
@@ -59,15 +60,14 @@ int assign_chcr_device(struct chcr_dev *
 	 * must go to the same device to maintain the ordering.
 	 */
 	mutex_lock(&dev_mutex); /* TODO ? */
-	u_ctx = list_first_entry(&uld_ctx_list, struct uld_ctx, entry);
-	if (!u_ctx) {
-		mutex_unlock(&dev_mutex);
-		return -ENXIO;
+	list_for_each_entry(u_ctx, &uld_ctx_list, entry)
+		if (u_ctx && u_ctx->dev) {
+			*dev = u_ctx->dev;
+			ret = 0;
+			break;
 	}
-
-	*dev = u_ctx->dev;
 	mutex_unlock(&dev_mutex);
-	return 0;
+	return ret;
 }
 
 static int chcr_dev_add(struct uld_ctx *u_ctx)
@@ -202,10 +202,8 @@ static int chcr_uld_state_change(void *h
 
 static int __init chcr_crypto_init(void)
 {
-	if (cxgb4_register_uld(CXGB4_ULD_CRYPTO, &chcr_uld_info)) {
+	if (cxgb4_register_uld(CXGB4_ULD_CRYPTO, &chcr_uld_info))
 		pr_err("ULD register fail: No chcr crypto support in cxgb4");
-		return -1;
-	}
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/crypto/chelsio/chcr_crypto.h linux-libre-4.10-rc8-gnu/drivers/crypto/chelsio/chcr_crypto.h
--- linux-libre-4.10-rc7-gnu/drivers/crypto/chelsio/chcr_crypto.h	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/crypto/chelsio/chcr_crypto.h	2017-02-12 16:03:20.000000000 -0500
@@ -158,6 +158,9 @@ struct ablk_ctx {
 };
 struct chcr_aead_reqctx {
 	struct	sk_buff	*skb;
+	struct scatterlist *dst;
+	struct scatterlist srcffwd[2];
+	struct scatterlist dstffwd[2];
 	short int dst_nents;
 	u16 verify;
 	u8 iv[CHCR_MAX_CRYPTO_IV_LEN];
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/crypto/qat/qat_c62x/adf_drv.c linux-libre-4.10-rc8-gnu/drivers/crypto/qat/qat_c62x/adf_drv.c
--- linux-libre-4.10-rc7-gnu/drivers/crypto/qat/qat_c62x/adf_drv.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/crypto/qat/qat_c62x/adf_drv.c	2017-02-12 16:03:20.000000000 -0500
@@ -233,7 +233,7 @@ static int adf_probe(struct pci_dev *pde
 			      &hw_data->accel_capabilities_mask);
 
 	/* Find and map all the device's BARS */
-	i = 0;
+	i = (hw_data->fuses & ADF_DEVICE_FUSECTL_MASK) ? 1 : 0;
 	bar_mask = pci_select_bars(pdev, IORESOURCE_MEM);
 	for_each_set_bit(bar_nr, (const unsigned long *)&bar_mask,
 			 ADF_PCI_MAX_BARS * 2) {
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/crypto/qat/qat_common/adf_accel_devices.h linux-libre-4.10-rc8-gnu/drivers/crypto/qat/qat_common/adf_accel_devices.h
--- linux-libre-4.10-rc7-gnu/drivers/crypto/qat/qat_common/adf_accel_devices.h	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/crypto/qat/qat_common/adf_accel_devices.h	2017-02-12 16:03:20.000000000 -0500
@@ -69,6 +69,7 @@
 #define ADF_ERRSOU5 (0x3A000 + 0xD8)
 #define ADF_DEVICE_FUSECTL_OFFSET 0x40
 #define ADF_DEVICE_LEGFUSE_OFFSET 0x4C
+#define ADF_DEVICE_FUSECTL_MASK 0x80000000
 #define ADF_PCI_MAX_BARS 3
 #define ADF_DEVICE_NAME_LENGTH 32
 #define ADF_ETR_MAX_RINGS_PER_BANK 16
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/crypto/qat/qat_common/qat_hal.c linux-libre-4.10-rc8-gnu/drivers/crypto/qat/qat_common/qat_hal.c
--- linux-libre-4.10-rc7-gnu/drivers/crypto/qat/qat_common/qat_hal.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/crypto/qat/qat_common/qat_hal.c	2017-02-12 16:03:20.000000000 -0500
@@ -456,7 +456,7 @@ static int qat_hal_init_esram(struct icp
 	unsigned int csr_val;
 	int times = 30;
 
-	if (handle->pci_dev->device == ADF_C3XXX_PCI_DEVICE_ID)
+	if (handle->pci_dev->device != ADF_DH895XCC_PCI_DEVICE_ID)
 		return 0;
 
 	csr_val = ADF_CSR_RD(csr_addr, 0);
@@ -716,7 +716,7 @@ int qat_hal_init(struct adf_accel_dev *a
 		(void __iomem *)((uintptr_t)handle->hal_cap_ae_xfer_csr_addr_v +
 				 LOCAL_TO_XFER_REG_OFFSET);
 	handle->pci_dev = pci_info->pci_dev;
-	if (handle->pci_dev->device != ADF_C3XXX_PCI_DEVICE_ID) {
+	if (handle->pci_dev->device == ADF_DH895XCC_PCI_DEVICE_ID) {
 		sram_bar =
 			&pci_info->pci_bars[hw_data->get_sram_bar_id(hw_data)];
 		handle->hal_sram_addr_v = sram_bar->virt_addr;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/gpu/drm/i915/i915_drv.c linux-libre-4.10-rc8-gnu/drivers/gpu/drm/i915/i915_drv.c
--- linux-libre-4.10-rc7-gnu/drivers/gpu/drm/i915/i915_drv.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/gpu/drm/i915/i915_drv.c	2017-02-12 16:03:20.000000000 -0500
@@ -213,7 +213,8 @@ static void intel_detect_pch(struct drm_
 			} else if (id == INTEL_PCH_KBP_DEVICE_ID_TYPE) {
 				dev_priv->pch_type = PCH_KBP;
 				DRM_DEBUG_KMS("Found KabyPoint PCH\n");
-				WARN_ON(!IS_KABYLAKE(dev_priv));
+				WARN_ON(!IS_SKYLAKE(dev_priv) &&
+					!IS_KABYLAKE(dev_priv));
 			} else if ((id == INTEL_PCH_P2X_DEVICE_ID_TYPE) ||
 				   (id == INTEL_PCH_P3X_DEVICE_ID_TYPE) ||
 				   ((id == INTEL_PCH_QEMU_DEVICE_ID_TYPE) &&
@@ -2427,6 +2428,7 @@ static int intel_runtime_resume(struct d
 	 * we can do is to hope that things will still work (and disable RPM).
 	 */
 	i915_gem_init_swizzling(dev_priv);
+	i915_gem_restore_fences(dev_priv);
 
 	intel_runtime_pm_enable_interrupts(dev_priv);
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/gpu/drm/i915/i915_gem.c linux-libre-4.10-rc8-gnu/drivers/gpu/drm/i915/i915_gem.c
--- linux-libre-4.10-rc7-gnu/drivers/gpu/drm/i915/i915_gem.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/gpu/drm/i915/i915_gem.c	2017-02-12 16:03:20.000000000 -0500
@@ -2010,8 +2010,16 @@ void i915_gem_runtime_suspend(struct drm
 	for (i = 0; i < dev_priv->num_fence_regs; i++) {
 		struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i];
 
-		if (WARN_ON(reg->pin_count))
-			continue;
+		/* Ideally we want to assert that the fence register is not
+		 * live at this point (i.e. that no piece of code will be
+		 * trying to write through fence + GTT, as that both violates
+		 * our tracking of activity and associated locking/barriers,
+		 * but also is illegal given that the hw is powered down).
+		 *
+		 * Previously we used reg->pin_count as a "liveness" indicator.
+		 * That is not sufficient, and we need a more fine-grained
+		 * tool if we want to have a sanity check here.
+		 */
 
 		if (!reg->vma)
 			continue;
@@ -3478,7 +3486,7 @@ i915_gem_object_pin_to_display_plane(str
 	vma->display_alignment = max_t(u64, vma->display_alignment, alignment);
 
 	/* Treat this as an end-of-frame, like intel_user_framebuffer_dirty() */
-	if (obj->cache_dirty) {
+	if (obj->cache_dirty || obj->base.write_domain == I915_GEM_DOMAIN_CPU) {
 		i915_gem_clflush_object(obj, true);
 		intel_fb_obj_flush(obj, false, ORIGIN_DIRTYFB);
 	}
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/gpu/drm/i915/i915_gem_execbuffer.c linux-libre-4.10-rc8-gnu/drivers/gpu/drm/i915/i915_gem_execbuffer.c
--- linux-libre-4.10-rc7-gnu/drivers/gpu/drm/i915/i915_gem_execbuffer.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/gpu/drm/i915/i915_gem_execbuffer.c	2017-02-12 16:03:20.000000000 -0500
@@ -1181,14 +1181,14 @@ validate_exec_list(struct drm_device *de
 			if (exec[i].offset !=
 			    gen8_canonical_addr(exec[i].offset & PAGE_MASK))
 				return -EINVAL;
-
-			/* From drm_mm perspective address space is continuous,
-			 * so from this point we're always using non-canonical
-			 * form internally.
-			 */
-			exec[i].offset = gen8_noncanonical_addr(exec[i].offset);
 		}
 
+		/* From drm_mm perspective address space is continuous,
+		 * so from this point we're always using non-canonical
+		 * form internally.
+		 */
+		exec[i].offset = gen8_noncanonical_addr(exec[i].offset);
+
 		if (exec[i].alignment && !is_power_of_2(exec[i].alignment))
 			return -EINVAL;
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/gpu/drm/i915/i915_gem_internal.c linux-libre-4.10-rc8-gnu/drivers/gpu/drm/i915/i915_gem_internal.c
--- linux-libre-4.10-rc7-gnu/drivers/gpu/drm/i915/i915_gem_internal.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/gpu/drm/i915/i915_gem_internal.c	2017-02-12 16:03:20.000000000 -0500
@@ -66,8 +66,16 @@ i915_gem_object_get_pages_internal(struc
 
 	max_order = MAX_ORDER;
 #ifdef CONFIG_SWIOTLB
-	if (swiotlb_nr_tbl()) /* minimum max swiotlb size is IO_TLB_SEGSIZE */
-		max_order = min(max_order, ilog2(IO_TLB_SEGPAGES));
+	if (swiotlb_nr_tbl()) {
+		unsigned int max_segment;
+
+		max_segment = swiotlb_max_segment();
+		if (max_segment) {
+			max_segment = max_t(unsigned int, max_segment,
+					    PAGE_SIZE) >> PAGE_SHIFT;
+			max_order = min(max_order, ilog2(max_segment));
+		}
+	}
 #endif
 
 	gfp = GFP_KERNEL | __GFP_HIGHMEM | __GFP_RECLAIMABLE;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/gpu/drm/i915/intel_display.c linux-libre-4.10-rc8-gnu/drivers/gpu/drm/i915/intel_display.c
--- linux-libre-4.10-rc7-gnu/drivers/gpu/drm/i915/intel_display.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/gpu/drm/i915/intel_display.c	2017-02-12 16:03:20.000000000 -0500
@@ -4262,10 +4262,10 @@ static void page_flip_completed(struct i
 	drm_crtc_vblank_put(&intel_crtc->base);
 
 	wake_up_all(&dev_priv->pending_flip_queue);
-	queue_work(dev_priv->wq, &work->unpin_work);
-
 	trace_i915_flip_complete(intel_crtc->plane,
 				 work->pending_flip_obj);
+
+	queue_work(dev_priv->wq, &work->unpin_work);
 }
 
 static int intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc)
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/gpu/drm/i915/intel_dpll_mgr.c linux-libre-4.10-rc8-gnu/drivers/gpu/drm/i915/intel_dpll_mgr.c
--- linux-libre-4.10-rc7-gnu/drivers/gpu/drm/i915/intel_dpll_mgr.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/gpu/drm/i915/intel_dpll_mgr.c	2017-02-12 16:03:20.000000000 -0500
@@ -1730,7 +1730,8 @@ bxt_get_dpll(struct intel_crtc *crtc,
 		return NULL;
 
 	if ((encoder->type == INTEL_OUTPUT_DP ||
-	     encoder->type == INTEL_OUTPUT_EDP) &&
+	     encoder->type == INTEL_OUTPUT_EDP ||
+	     encoder->type == INTEL_OUTPUT_DP_MST) &&
 	    !bxt_ddi_dp_set_dpll_hw_state(clock, &dpll_hw_state))
 		return NULL;
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/gpu/drm/vc4/vc4_plane.c linux-libre-4.10-rc8-gnu/drivers/gpu/drm/vc4/vc4_plane.c
--- linux-libre-4.10-rc7-gnu/drivers/gpu/drm/vc4/vc4_plane.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/gpu/drm/vc4/vc4_plane.c	2017-02-12 16:03:20.000000000 -0500
@@ -858,7 +858,7 @@ struct drm_plane *vc4_plane_init(struct
 		}
 	}
 	plane = &vc4_plane->base;
-	ret = drm_universal_plane_init(dev, plane, 0xff,
+	ret = drm_universal_plane_init(dev, plane, 0,
 				       &vc4_plane_funcs,
 				       formats, num_formats,
 				       type, NULL);
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c linux-libre-4.10-rc8-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
--- linux-libre-4.10-rc7-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c	2017-02-12 16:03:20.000000000 -0500
@@ -481,8 +481,7 @@ static int vmw_fb_kms_framebuffer(struct
 	mode_cmd.height = var->yres;
 	mode_cmd.pitches[0] = ((var->bits_per_pixel + 7) / 8) * mode_cmd.width;
 	mode_cmd.pixel_format =
-		drm_mode_legacy_fb_format(var->bits_per_pixel,
-			((var->bits_per_pixel + 7) / 8) * mode_cmd.width);
+		drm_mode_legacy_fb_format(var->bits_per_pixel, depth);
 
 	cur_fb = par->set_fb;
 	if (cur_fb && cur_fb->width == mode_cmd.width &&
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/i2c/busses/i2c-piix4.c linux-libre-4.10-rc8-gnu/drivers/i2c/busses/i2c-piix4.c
--- linux-libre-4.10-rc7-gnu/drivers/i2c/busses/i2c-piix4.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/i2c/busses/i2c-piix4.c	2017-02-12 16:03:20.000000000 -0500
@@ -58,7 +58,7 @@
 #define SMBSLVDAT	(0xC + piix4_smba)
 
 /* count for request_region */
-#define SMBIOSIZE	8
+#define SMBIOSIZE	9
 
 /* PCI Address Constants */
 #define SMBBA		0x090
@@ -592,6 +592,8 @@ static s32 piix4_access_sb800(struct i2c
 	u8 port;
 	int retval;
 
+	mutex_lock(&piix4_mutex_sb800);
+
 	/* Request the SMBUS semaphore, avoid conflicts with the IMC */
 	smbslvcnt  = inb_p(SMBSLVCNT);
 	do {
@@ -605,10 +607,10 @@ static s32 piix4_access_sb800(struct i2c
 		usleep_range(1000, 2000);
 	} while (--retries);
 	/* SMBus is still owned by the IMC, we give up */
-	if (!retries)
+	if (!retries) {
+		mutex_unlock(&piix4_mutex_sb800);
 		return -EBUSY;
-
-	mutex_lock(&piix4_mutex_sb800);
+	}
 
 	outb_p(piix4_port_sel_sb800, SB800_PIIX4_SMB_IDX);
 	smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1);
@@ -623,11 +625,11 @@ static s32 piix4_access_sb800(struct i2c
 
 	outb_p(smba_en_lo, SB800_PIIX4_SMB_IDX + 1);
 
-	mutex_unlock(&piix4_mutex_sb800);
-
 	/* Release the semaphore */
 	outb_p(smbslvcnt | 0x20, SMBSLVCNT);
 
+	mutex_unlock(&piix4_mutex_sb800);
+
 	return retval;
 }
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/infiniband/sw/rxe/rxe_mr.c linux-libre-4.10-rc8-gnu/drivers/infiniband/sw/rxe/rxe_mr.c
--- linux-libre-4.10-rc7-gnu/drivers/infiniband/sw/rxe/rxe_mr.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/infiniband/sw/rxe/rxe_mr.c	2017-02-12 16:03:20.000000000 -0500
@@ -59,9 +59,11 @@ int mem_check_range(struct rxe_mem *mem,
 
 	case RXE_MEM_TYPE_MR:
 	case RXE_MEM_TYPE_FMR:
-		return ((iova < mem->iova) ||
-			((iova + length) > (mem->iova + mem->length))) ?
-			-EFAULT : 0;
+		if (iova < mem->iova ||
+		    length > mem->length ||
+		    iova > mem->iova + mem->length - length)
+			return -EFAULT;
+		return 0;
 
 	default:
 		return -EFAULT;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/infiniband/sw/rxe/rxe_resp.c linux-libre-4.10-rc8-gnu/drivers/infiniband/sw/rxe/rxe_resp.c
--- linux-libre-4.10-rc7-gnu/drivers/infiniband/sw/rxe/rxe_resp.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/infiniband/sw/rxe/rxe_resp.c	2017-02-12 16:03:20.000000000 -0500
@@ -479,7 +479,7 @@ static enum resp_states check_rkey(struc
 				goto err2;
 			}
 
-			resid = mtu;
+			qp->resp.resid = mtu;
 		} else {
 			if (pktlen != resid) {
 				state = RESPST_ERR_LENGTH;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/input/misc/uinput.c linux-libre-4.10-rc8-gnu/drivers/input/misc/uinput.c
--- linux-libre-4.10-rc7-gnu/drivers/input/misc/uinput.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/input/misc/uinput.c	2017-02-12 16:03:20.000000000 -0500
@@ -263,13 +263,21 @@ static int uinput_create_device(struct u
 		return -EINVAL;
 	}
 
-	if (test_bit(ABS_MT_SLOT, dev->absbit)) {
-		nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1;
-		error = input_mt_init_slots(dev, nslot, 0);
-		if (error)
+	if (test_bit(EV_ABS, dev->evbit)) {
+		input_alloc_absinfo(dev);
+		if (!dev->absinfo) {
+			error = -EINVAL;
 			goto fail1;
-	} else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) {
-		input_set_events_per_packet(dev, 60);
+		}
+
+		if (test_bit(ABS_MT_SLOT, dev->absbit)) {
+			nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1;
+			error = input_mt_init_slots(dev, nslot, 0);
+			if (error)
+				goto fail1;
+		} else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) {
+			input_set_events_per_packet(dev, 60);
+		}
 	}
 
 	if (test_bit(EV_FF, dev->evbit) && !udev->ff_effects_max) {
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/input/rmi4/Kconfig linux-libre-4.10-rc8-gnu/drivers/input/rmi4/Kconfig
--- linux-libre-4.10-rc7-gnu/drivers/input/rmi4/Kconfig	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/input/rmi4/Kconfig	2017-02-12 16:03:20.000000000 -0500
@@ -42,13 +42,19 @@ config RMI4_SMB
 config RMI4_F03
         bool "RMI4 Function 03 (PS2 Guest)"
 	depends on RMI4_CORE
-	depends on SERIO=y || RMI4_CORE=SERIO
         help
           Say Y here if you want to add support for RMI4 function 03.
 
           Function 03 provides PS2 guest support for RMI4 devices. This
           includes support for TrackPoints on TouchPads.
 
+config RMI4_F03_SERIO
+	tristate
+	depends on RMI4_CORE
+	depends on RMI4_F03
+	default RMI4_CORE
+	select SERIO
+
 config RMI4_2D_SENSOR
 	bool
 	depends on RMI4_CORE
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/irqchip/irq-keystone.c linux-libre-4.10-rc8-gnu/drivers/irqchip/irq-keystone.c
--- linux-libre-4.10-rc7-gnu/drivers/irqchip/irq-keystone.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/irqchip/irq-keystone.c	2017-02-12 16:03:20.000000000 -0500
@@ -19,9 +19,9 @@
 #include <linux/bitops.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/interrupt.h>
 #include <linux/irqdomain.h>
 #include <linux/irqchip.h>
-#include <linux/irqchip/chained_irq.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
 #include <linux/mfd/syscon.h>
@@ -39,6 +39,7 @@ struct keystone_irq_device {
 	struct irq_domain	*irqd;
 	struct regmap		*devctrl_regs;
 	u32			devctrl_offset;
+	raw_spinlock_t		wa_lock;
 };
 
 static inline u32 keystone_irq_readl(struct keystone_irq_device *kirq)
@@ -83,17 +84,15 @@ static void keystone_irq_ack(struct irq_
 	/* nothing to do here */
 }
 
-static void keystone_irq_handler(struct irq_desc *desc)
+static irqreturn_t keystone_irq_handler(int irq, void *keystone_irq)
 {
-	unsigned int irq = irq_desc_get_irq(desc);
-	struct keystone_irq_device *kirq = irq_desc_get_handler_data(desc);
+	struct keystone_irq_device *kirq = keystone_irq;
+	unsigned long wa_lock_flags;
 	unsigned long pending;
 	int src, virq;
 
 	dev_dbg(kirq->dev, "start irq %d\n", irq);
 
-	chained_irq_enter(irq_desc_get_chip(desc), desc);
-
 	pending = keystone_irq_readl(kirq);
 	keystone_irq_writel(kirq, pending);
 
@@ -111,13 +110,15 @@ static void keystone_irq_handler(struct
 			if (!virq)
 				dev_warn(kirq->dev, "spurious irq detected hwirq %d, virq %d\n",
 					 src, virq);
+			raw_spin_lock_irqsave(&kirq->wa_lock, wa_lock_flags);
 			generic_handle_irq(virq);
+			raw_spin_unlock_irqrestore(&kirq->wa_lock,
+						   wa_lock_flags);
 		}
 	}
 
-	chained_irq_exit(irq_desc_get_chip(desc), desc);
-
 	dev_dbg(kirq->dev, "end irq %d\n", irq);
+	return IRQ_HANDLED;
 }
 
 static int keystone_irq_map(struct irq_domain *h, unsigned int virq,
@@ -182,9 +183,16 @@ static int keystone_irq_probe(struct pla
 		return -ENODEV;
 	}
 
+	raw_spin_lock_init(&kirq->wa_lock);
+
 	platform_set_drvdata(pdev, kirq);
 
-	irq_set_chained_handler_and_data(kirq->irq, keystone_irq_handler, kirq);
+	ret = request_irq(kirq->irq, keystone_irq_handler,
+			  0, dev_name(dev), kirq);
+	if (ret) {
+		irq_domain_remove(kirq->irqd);
+		return ret;
+	}
 
 	/* clear all source bits */
 	keystone_irq_writel(kirq, ~0x0);
@@ -199,6 +207,8 @@ static int keystone_irq_remove(struct pl
 	struct keystone_irq_device *kirq = platform_get_drvdata(pdev);
 	int hwirq;
 
+	free_irq(kirq->irq, kirq);
+
 	for (hwirq = 0; hwirq < KEYSTONE_N_IRQ; hwirq++)
 		irq_dispose_mapping(irq_find_mapping(kirq->irqd, hwirq));
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/irqchip/irq-mxs.c linux-libre-4.10-rc8-gnu/drivers/irqchip/irq-mxs.c
--- linux-libre-4.10-rc7-gnu/drivers/irqchip/irq-mxs.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/irqchip/irq-mxs.c	2017-02-12 16:03:20.000000000 -0500
@@ -131,12 +131,16 @@ static struct irq_chip mxs_icoll_chip =
 	.irq_ack = icoll_ack_irq,
 	.irq_mask = icoll_mask_irq,
 	.irq_unmask = icoll_unmask_irq,
+	.flags = IRQCHIP_MASK_ON_SUSPEND |
+		 IRQCHIP_SKIP_SET_WAKE,
 };
 
 static struct irq_chip asm9260_icoll_chip = {
 	.irq_ack = icoll_ack_irq,
 	.irq_mask = asm9260_mask_irq,
 	.irq_unmask = asm9260_unmask_irq,
+	.flags = IRQCHIP_MASK_ON_SUSPEND |
+		 IRQCHIP_SKIP_SET_WAKE,
 };
 
 asmlinkage void __exception_irq_entry icoll_handle_irq(struct pt_regs *regs)
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/md/dm-crypt.c linux-libre-4.10-rc8-gnu/drivers/md/dm-crypt.c
--- linux-libre-4.10-rc7-gnu/drivers/md/dm-crypt.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/md/dm-crypt.c	2017-02-12 16:03:20.000000000 -0500
@@ -1534,18 +1534,18 @@ static int crypt_set_keyring_key(struct
 		return PTR_ERR(key);
 	}
 
-	rcu_read_lock();
+	down_read(&key->sem);
 
 	ukp = user_key_payload(key);
 	if (!ukp) {
-		rcu_read_unlock();
+		up_read(&key->sem);
 		key_put(key);
 		kzfree(new_key_string);
 		return -EKEYREVOKED;
 	}
 
 	if (cc->key_size != ukp->datalen) {
-		rcu_read_unlock();
+		up_read(&key->sem);
 		key_put(key);
 		kzfree(new_key_string);
 		return -EINVAL;
@@ -1553,7 +1553,7 @@ static int crypt_set_keyring_key(struct
 
 	memcpy(cc->key, ukp->data, cc->key_size);
 
-	rcu_read_unlock();
+	up_read(&key->sem);
 	key_put(key);
 
 	/* clear the flag since following operations may invalidate previously valid key */
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/md/dm-mpath.c linux-libre-4.10-rc8-gnu/drivers/md/dm-mpath.c
--- linux-libre-4.10-rc7-gnu/drivers/md/dm-mpath.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/md/dm-mpath.c	2017-02-12 16:03:20.000000000 -0500
@@ -427,7 +427,7 @@ static struct pgpath *choose_pgpath(stru
 	unsigned long flags;
 	struct priority_group *pg;
 	struct pgpath *pgpath;
-	bool bypassed = true;
+	unsigned bypassed = 1;
 
 	if (!atomic_read(&m->nr_valid_paths)) {
 		clear_bit(MPATHF_QUEUE_IO, &m->flags);
@@ -466,7 +466,7 @@ check_current_pg:
 	 */
 	do {
 		list_for_each_entry(pg, &m->priority_groups, list) {
-			if (pg->bypassed == bypassed)
+			if (pg->bypassed == !!bypassed)
 				continue;
 			pgpath = choose_path_in_pg(m, pg, nr_bytes);
 			if (!IS_ERR_OR_NULL(pgpath)) {
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/md/dm-rq.c linux-libre-4.10-rc8-gnu/drivers/md/dm-rq.c
--- linux-libre-4.10-rc7-gnu/drivers/md/dm-rq.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/md/dm-rq.c	2017-02-12 16:03:20.000000000 -0500
@@ -779,6 +779,10 @@ static void dm_old_request_fn(struct req
 		int srcu_idx;
 		struct dm_table *map = dm_get_live_table(md, &srcu_idx);
 
+		if (unlikely(!map)) {
+			dm_put_live_table(md, srcu_idx);
+			return;
+		}
 		ti = dm_table_find_target(map, pos);
 		dm_put_live_table(md, srcu_idx);
 	}
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/media/cec/cec-adap.c linux-libre-4.10-rc8-gnu/drivers/media/cec/cec-adap.c
--- linux-libre-4.10-rc7-gnu/drivers/media/cec/cec-adap.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/media/cec/cec-adap.c	2017-02-12 16:03:20.000000000 -0500
@@ -1206,7 +1206,7 @@ static int cec_config_thread_func(void *
 		las->log_addr[i] = CEC_LOG_ADDR_INVALID;
 		if (last_la == CEC_LOG_ADDR_INVALID ||
 		    last_la == CEC_LOG_ADDR_UNREGISTERED ||
-		    !(last_la & type2mask[type]))
+		    !((1 << last_la) & type2mask[type]))
 			last_la = la_list[0];
 
 		err = cec_config_log_addr(adap, i, last_la);
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/mmc/host/mmci.c linux-libre-4.10-rc8-gnu/drivers/mmc/host/mmci.c
--- linux-libre-4.10-rc7-gnu/drivers/mmc/host/mmci.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/mmc/host/mmci.c	2017-02-12 16:03:20.000000000 -0500
@@ -1023,7 +1023,12 @@ mmci_cmd_irq(struct mmci_host *host, str
 		if (!host->busy_status && busy_resp &&
 		    !(status & (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT)) &&
 		    (readl(base + MMCISTATUS) & host->variant->busy_detect_flag)) {
-			/* Unmask the busy IRQ */
+
+			/* Clear the busy start IRQ */
+			writel(host->variant->busy_detect_mask,
+			       host->base + MMCICLEAR);
+
+			/* Unmask the busy end IRQ */
 			writel(readl(base + MMCIMASK0) |
 			       host->variant->busy_detect_mask,
 			       base + MMCIMASK0);
@@ -1038,10 +1043,14 @@ mmci_cmd_irq(struct mmci_host *host, str
 
 		/*
 		 * At this point we are not busy with a command, we have
-		 * not received a new busy request, mask the busy IRQ and
-		 * fall through to process the IRQ.
+		 * not received a new busy request, clear and mask the busy
+		 * end IRQ and fall through to process the IRQ.
 		 */
 		if (host->busy_status) {
+
+			writel(host->variant->busy_detect_mask,
+			       host->base + MMCICLEAR);
+
 			writel(readl(base + MMCIMASK0) &
 			       ~host->variant->busy_detect_mask,
 			       base + MMCIMASK0);
@@ -1283,12 +1292,21 @@ static irqreturn_t mmci_irq(int irq, voi
 		}
 
 		/*
-		 * We intentionally clear the MCI_ST_CARDBUSY IRQ here (if it's
-		 * enabled) since the HW seems to be triggering the IRQ on both
-		 * edges while monitoring DAT0 for busy completion.
+		 * We intentionally clear the MCI_ST_CARDBUSY IRQ (if it's
+		 * enabled) in mmci_cmd_irq() function where ST Micro busy
+		 * detection variant is handled. Considering the HW seems to be
+		 * triggering the IRQ on both edges while monitoring DAT0 for
+		 * busy completion and that same status bit is used to monitor
+		 * start and end of busy detection, special care must be taken
+		 * to make sure that both start and end interrupts are always
+		 * cleared one after the other.
 		 */
 		status &= readl(host->base + MMCIMASK0);
-		writel(status, host->base + MMCICLEAR);
+		if (host->variant->busy_detect)
+			writel(status & ~host->variant->busy_detect_mask,
+			       host->base + MMCICLEAR);
+		else
+			writel(status, host->base + MMCICLEAR);
 
 		dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status);
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/net/ethernet/cavium/thunder/thunder_bgx.c linux-libre-4.10-rc8-gnu/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
--- linux-libre-4.10-rc7-gnu/drivers/net/ethernet/cavium/thunder/thunder_bgx.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/net/ethernet/cavium/thunder/thunder_bgx.c	2017-02-12 16:03:20.000000000 -0500
@@ -31,6 +31,7 @@ struct lmac {
 	u8                      lmac_type;
 	u8                      lane_to_sds;
 	bool                    use_training;
+	bool                    autoneg;
 	bool			link_up;
 	int			lmacid; /* ID within BGX */
 	int			lmacid_bd; /* ID on board */
@@ -461,7 +462,17 @@ static int bgx_lmac_sgmii_init(struct bg
 	/* power down, reset autoneg, autoneg enable */
 	cfg = bgx_reg_read(bgx, lmacid, BGX_GMP_PCS_MRX_CTL);
 	cfg &= ~PCS_MRX_CTL_PWR_DN;
-	cfg |= (PCS_MRX_CTL_RST_AN | PCS_MRX_CTL_AN_EN);
+	cfg |= PCS_MRX_CTL_RST_AN;
+	if (lmac->phydev) {
+		cfg |= PCS_MRX_CTL_AN_EN;
+	} else {
+		/* In scenarios where PHY driver is not present or it's a
+		 * non-standard PHY, FW sets AN_EN to inform Linux driver
+		 * to do auto-neg and link polling or not.
+		 */
+		if (cfg & PCS_MRX_CTL_AN_EN)
+			lmac->autoneg = true;
+	}
 	bgx_reg_write(bgx, lmacid, BGX_GMP_PCS_MRX_CTL, cfg);
 
 	if (lmac->lmac_type == BGX_MODE_QSGMII) {
@@ -472,7 +483,7 @@ static int bgx_lmac_sgmii_init(struct bg
 		return 0;
 	}
 
-	if (lmac->lmac_type == BGX_MODE_SGMII) {
+	if ((lmac->lmac_type == BGX_MODE_SGMII) && lmac->phydev) {
 		if (bgx_poll_reg(bgx, lmacid, BGX_GMP_PCS_MRX_STATUS,
 				 PCS_MRX_STATUS_AN_CPT, false)) {
 			dev_err(&bgx->pdev->dev, "BGX AN_CPT not completed\n");
@@ -678,12 +689,71 @@ static int bgx_xaui_check_link(struct lm
 	return -1;
 }
 
+static void bgx_poll_for_sgmii_link(struct lmac *lmac)
+{
+	u64 pcs_link, an_result;
+	u8 speed;
+
+	pcs_link = bgx_reg_read(lmac->bgx, lmac->lmacid,
+				BGX_GMP_PCS_MRX_STATUS);
+
+	/*Link state bit is sticky, read it again*/
+	if (!(pcs_link & PCS_MRX_STATUS_LINK))
+		pcs_link = bgx_reg_read(lmac->bgx, lmac->lmacid,
+					BGX_GMP_PCS_MRX_STATUS);
+
+	if (bgx_poll_reg(lmac->bgx, lmac->lmacid, BGX_GMP_PCS_MRX_STATUS,
+			 PCS_MRX_STATUS_AN_CPT, false)) {
+		lmac->link_up = false;
+		lmac->last_speed = SPEED_UNKNOWN;
+		lmac->last_duplex = DUPLEX_UNKNOWN;
+		goto next_poll;
+	}
+
+	lmac->link_up = ((pcs_link & PCS_MRX_STATUS_LINK) != 0) ? true : false;
+	an_result = bgx_reg_read(lmac->bgx, lmac->lmacid,
+				 BGX_GMP_PCS_ANX_AN_RESULTS);
+
+	speed = (an_result >> 3) & 0x3;
+	lmac->last_duplex = (an_result >> 1) & 0x1;
+	switch (speed) {
+	case 0:
+		lmac->last_speed = 10;
+		break;
+	case 1:
+		lmac->last_speed = 100;
+		break;
+	case 2:
+		lmac->last_speed = 1000;
+		break;
+	default:
+		lmac->link_up = false;
+		lmac->last_speed = SPEED_UNKNOWN;
+		lmac->last_duplex = DUPLEX_UNKNOWN;
+		break;
+	}
+
+next_poll:
+
+	if (lmac->last_link != lmac->link_up) {
+		if (lmac->link_up)
+			bgx_sgmii_change_link_state(lmac);
+		lmac->last_link = lmac->link_up;
+	}
+
+	queue_delayed_work(lmac->check_link, &lmac->dwork, HZ * 3);
+}
+
 static void bgx_poll_for_link(struct work_struct *work)
 {
 	struct lmac *lmac;
 	u64 spu_link, smu_link;
 
 	lmac = container_of(work, struct lmac, dwork.work);
+	if (lmac->is_sgmii) {
+		bgx_poll_for_sgmii_link(lmac);
+		return;
+	}
 
 	/* Receive link is latching low. Force it high and verify it */
 	bgx_reg_modify(lmac->bgx, lmac->lmacid,
@@ -775,9 +845,21 @@ static int bgx_lmac_enable(struct bgx *b
 	    (lmac->lmac_type != BGX_MODE_XLAUI) &&
 	    (lmac->lmac_type != BGX_MODE_40G_KR) &&
 	    (lmac->lmac_type != BGX_MODE_10G_KR)) {
-		if (!lmac->phydev)
-			return -ENODEV;
-
+		if (!lmac->phydev) {
+			if (lmac->autoneg) {
+				bgx_reg_write(bgx, lmacid,
+					      BGX_GMP_PCS_LINKX_TIMER,
+					      PCS_LINKX_TIMER_COUNT);
+				goto poll;
+			} else {
+				/* Default to below link speed and duplex */
+				lmac->link_up = true;
+				lmac->last_speed = 1000;
+				lmac->last_duplex = 1;
+				bgx_sgmii_change_link_state(lmac);
+				return 0;
+			}
+		}
 		lmac->phydev->dev_flags = 0;
 
 		if (phy_connect_direct(&lmac->netdev, lmac->phydev,
@@ -786,15 +868,17 @@ static int bgx_lmac_enable(struct bgx *b
 			return -ENODEV;
 
 		phy_start_aneg(lmac->phydev);
-	} else {
-		lmac->check_link = alloc_workqueue("check_link", WQ_UNBOUND |
-						   WQ_MEM_RECLAIM, 1);
-		if (!lmac->check_link)
-			return -ENOMEM;
-		INIT_DELAYED_WORK(&lmac->dwork, bgx_poll_for_link);
-		queue_delayed_work(lmac->check_link, &lmac->dwork, 0);
+		return 0;
 	}
 
+poll:
+	lmac->check_link = alloc_workqueue("check_link", WQ_UNBOUND |
+					   WQ_MEM_RECLAIM, 1);
+	if (!lmac->check_link)
+		return -ENOMEM;
+	INIT_DELAYED_WORK(&lmac->dwork, bgx_poll_for_link);
+	queue_delayed_work(lmac->check_link, &lmac->dwork, 0);
+
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/net/ethernet/cavium/thunder/thunder_bgx.h linux-libre-4.10-rc8-gnu/drivers/net/ethernet/cavium/thunder/thunder_bgx.h
--- linux-libre-4.10-rc7-gnu/drivers/net/ethernet/cavium/thunder/thunder_bgx.h	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/net/ethernet/cavium/thunder/thunder_bgx.h	2017-02-12 16:03:20.000000000 -0500
@@ -153,10 +153,15 @@
 #define	 PCS_MRX_CTL_LOOPBACK1			BIT_ULL(14)
 #define	 PCS_MRX_CTL_RESET			BIT_ULL(15)
 #define BGX_GMP_PCS_MRX_STATUS		0x30008
+#define	 PCS_MRX_STATUS_LINK			BIT_ULL(2)
 #define	 PCS_MRX_STATUS_AN_CPT			BIT_ULL(5)
+#define BGX_GMP_PCS_ANX_ADV		0x30010
 #define BGX_GMP_PCS_ANX_AN_RESULTS	0x30020
+#define BGX_GMP_PCS_LINKX_TIMER		0x30040
+#define PCS_LINKX_TIMER_COUNT			0x1E84
 #define BGX_GMP_PCS_SGM_AN_ADV		0x30068
 #define BGX_GMP_PCS_MISCX_CTL		0x30078
+#define  PCS_MISC_CTL_MODE			BIT_ULL(8)
 #define  PCS_MISC_CTL_DISP_EN			BIT_ULL(13)
 #define  PCS_MISC_CTL_GMX_ENO			BIT_ULL(11)
 #define  PCS_MISC_CTL_SAMP_PT_MASK	0x7Full
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h linux-libre-4.10-rc8-gnu/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
--- linux-libre-4.10-rc7-gnu/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h	2017-02-12 16:03:20.000000000 -0500
@@ -1014,9 +1014,7 @@
 
 static inline void dsaf_write_reg(void __iomem *base, u32 reg, u32 value)
 {
-	u8 __iomem *reg_addr = ACCESS_ONCE(base);
-
-	writel(value, reg_addr + reg);
+	writel(value, base + reg);
 }
 
 #define dsaf_write_dev(a, reg, value) \
@@ -1024,9 +1022,7 @@ static inline void dsaf_write_reg(void _
 
 static inline u32 dsaf_read_reg(u8 __iomem *base, u32 reg)
 {
-	u8 __iomem *reg_addr = ACCESS_ONCE(base);
-
-	return readl(reg_addr + reg);
+	return readl(base + reg);
 }
 
 static inline void dsaf_write_syscon(struct regmap *base, u32 reg, u32 value)
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/net/ethernet/hisilicon/hns/hns_enet.c linux-libre-4.10-rc8-gnu/drivers/net/ethernet/hisilicon/hns/hns_enet.c
--- linux-libre-4.10-rc7-gnu/drivers/net/ethernet/hisilicon/hns/hns_enet.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/net/ethernet/hisilicon/hns/hns_enet.c	2017-02-12 16:03:20.000000000 -0500
@@ -305,8 +305,8 @@ int hns_nic_net_xmit_hw(struct net_devic
 			struct hns_nic_ring_data *ring_data)
 {
 	struct hns_nic_priv *priv = netdev_priv(ndev);
-	struct device *dev = priv->dev;
 	struct hnae_ring *ring = ring_data->ring;
+	struct device *dev = ring_to_dev(ring);
 	struct netdev_queue *dev_queue;
 	struct skb_frag_struct *frag;
 	int buf_num;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c linux-libre-4.10-rc8-gnu/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
--- linux-libre-4.10-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c	2017-02-12 16:03:20.000000000 -0500
@@ -1099,7 +1099,7 @@ static int mlx4_en_set_ringparam(struct
 	memcpy(&new_prof, priv->prof, sizeof(struct mlx4_en_port_profile));
 	new_prof.tx_ring_size = tx_size;
 	new_prof.rx_ring_size = rx_size;
-	err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof);
+	err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof, true);
 	if (err)
 		goto out;
 
@@ -1774,7 +1774,7 @@ static int mlx4_en_set_channels(struct n
 	new_prof.tx_ring_num[TX_XDP] = xdp_count;
 	new_prof.rx_ring_num = channel->rx_count;
 
-	err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof);
+	err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof, true);
 	if (err)
 		goto out;
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/en_netdev.c linux-libre-4.10-rc8-gnu/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
--- linux-libre-4.10-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/en_netdev.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/net/ethernet/mellanox/mlx4/en_netdev.c	2017-02-12 16:03:20.000000000 -0500
@@ -2042,6 +2042,8 @@ static void mlx4_en_free_resources(struc
 			if (priv->tx_cq[t] && priv->tx_cq[t][i])
 				mlx4_en_destroy_cq(priv, &priv->tx_cq[t][i]);
 		}
+		kfree(priv->tx_ring[t]);
+		kfree(priv->tx_cq[t]);
 	}
 
 	for (i = 0; i < priv->rx_ring_num; i++) {
@@ -2184,9 +2186,11 @@ static void mlx4_en_update_priv(struct m
 
 int mlx4_en_try_alloc_resources(struct mlx4_en_priv *priv,
 				struct mlx4_en_priv *tmp,
-				struct mlx4_en_port_profile *prof)
+				struct mlx4_en_port_profile *prof,
+				bool carry_xdp_prog)
 {
-	int t;
+	struct bpf_prog *xdp_prog;
+	int i, t;
 
 	mlx4_en_copy_priv(tmp, priv, prof);
 
@@ -2200,6 +2204,23 @@ int mlx4_en_try_alloc_resources(struct m
 		}
 		return -ENOMEM;
 	}
+
+	/* All rx_rings has the same xdp_prog.  Pick the first one. */
+	xdp_prog = rcu_dereference_protected(
+		priv->rx_ring[0]->xdp_prog,
+		lockdep_is_held(&priv->mdev->state_lock));
+
+	if (xdp_prog && carry_xdp_prog) {
+		xdp_prog = bpf_prog_add(xdp_prog, tmp->rx_ring_num);
+		if (IS_ERR(xdp_prog)) {
+			mlx4_en_free_resources(tmp);
+			return PTR_ERR(xdp_prog);
+		}
+		for (i = 0; i < tmp->rx_ring_num; i++)
+			rcu_assign_pointer(tmp->rx_ring[i]->xdp_prog,
+					   xdp_prog);
+	}
+
 	return 0;
 }
 
@@ -2214,7 +2235,6 @@ void mlx4_en_destroy_netdev(struct net_d
 {
 	struct mlx4_en_priv *priv = netdev_priv(dev);
 	struct mlx4_en_dev *mdev = priv->mdev;
-	int t;
 
 	en_dbg(DRV, priv, "Destroying netdev on port:%d\n", priv->port);
 
@@ -2248,11 +2268,6 @@ void mlx4_en_destroy_netdev(struct net_d
 	mlx4_en_free_resources(priv);
 	mutex_unlock(&mdev->state_lock);
 
-	for (t = 0; t < MLX4_EN_NUM_TX_TYPES; t++) {
-		kfree(priv->tx_ring[t]);
-		kfree(priv->tx_cq[t]);
-	}
-
 	free_netdev(dev);
 }
 
@@ -2755,7 +2770,7 @@ static int mlx4_xdp_set(struct net_devic
 		en_warn(priv, "Reducing the number of TX rings, to not exceed the max total rings number.\n");
 	}
 
-	err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof);
+	err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof, false);
 	if (err) {
 		if (prog)
 			bpf_prog_sub(prog, priv->rx_ring_num - 1);
@@ -3499,7 +3514,7 @@ int mlx4_en_reset_config(struct net_devi
 	memcpy(&new_prof, priv->prof, sizeof(struct mlx4_en_port_profile));
 	memcpy(&new_prof.hwtstamp_config, &ts_config, sizeof(ts_config));
 
-	err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof);
+	err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof, true);
 	if (err)
 		goto out;
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/en_rx.c linux-libre-4.10-rc8-gnu/drivers/net/ethernet/mellanox/mlx4/en_rx.c
--- linux-libre-4.10-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/en_rx.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/net/ethernet/mellanox/mlx4/en_rx.c	2017-02-12 16:03:20.000000000 -0500
@@ -514,8 +514,11 @@ void mlx4_en_recover_from_oom(struct mlx
 		return;
 
 	for (ring = 0; ring < priv->rx_ring_num; ring++) {
-		if (mlx4_en_is_ring_empty(priv->rx_ring[ring]))
+		if (mlx4_en_is_ring_empty(priv->rx_ring[ring])) {
+			local_bh_disable();
 			napi_reschedule(&priv->rx_cq[ring]->napi);
+			local_bh_enable();
+		}
 	}
 }
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h linux-libre-4.10-rc8-gnu/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
--- linux-libre-4.10-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h	2017-02-12 16:03:20.000000000 -0500
@@ -679,7 +679,8 @@ void mlx4_en_set_stats_bitmap(struct mlx
 
 int mlx4_en_try_alloc_resources(struct mlx4_en_priv *priv,
 				struct mlx4_en_priv *tmp,
-				struct mlx4_en_port_profile *prof);
+				struct mlx4_en_port_profile *prof,
+				bool carry_xdp_prog);
 void mlx4_en_safe_replace_resources(struct mlx4_en_priv *priv,
 				    struct mlx4_en_priv *tmp);
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/net/hamradio/mkiss.c linux-libre-4.10-rc8-gnu/drivers/net/hamradio/mkiss.c
--- linux-libre-4.10-rc7-gnu/drivers/net/hamradio/mkiss.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/net/hamradio/mkiss.c	2017-02-12 16:03:20.000000000 -0500
@@ -648,8 +648,8 @@ static void ax_setup(struct net_device *
 {
 	/* Finish setting up the DEVICE info. */
 	dev->mtu             = AX_MTU;
-	dev->hard_header_len = 0;
-	dev->addr_len        = 0;
+	dev->hard_header_len = AX25_MAX_HEADER_LEN;
+	dev->addr_len        = AX25_ADDR_LEN;
 	dev->type            = ARPHRD_AX25;
 	dev->tx_queue_len    = 10;
 	dev->header_ops      = &ax25_header_ops;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/net/loopback.c linux-libre-4.10-rc8-gnu/drivers/net/loopback.c
--- linux-libre-4.10-rc7-gnu/drivers/net/loopback.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/net/loopback.c	2017-02-12 16:03:20.000000000 -0500
@@ -164,6 +164,7 @@ static void loopback_setup(struct net_de
 {
 	dev->mtu		= 64 * 1024;
 	dev->hard_header_len	= ETH_HLEN;	/* 14	*/
+	dev->min_header_len	= ETH_HLEN;	/* 14	*/
 	dev->addr_len		= ETH_ALEN;	/* 6	*/
 	dev->type		= ARPHRD_LOOPBACK;	/* 0x0001*/
 	dev->flags		= IFF_LOOPBACK;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/net/macvtap.c linux-libre-4.10-rc8-gnu/drivers/net/macvtap.c
--- linux-libre-4.10-rc7-gnu/drivers/net/macvtap.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/net/macvtap.c	2017-02-12 16:03:20.000000000 -0500
@@ -681,7 +681,7 @@ static ssize_t macvtap_get_user(struct m
 	size_t linear;
 
 	if (q->flags & IFF_VNET_HDR) {
-		vnet_hdr_len = q->vnet_hdr_sz;
+		vnet_hdr_len = READ_ONCE(q->vnet_hdr_sz);
 
 		err = -EINVAL;
 		if (len < vnet_hdr_len)
@@ -820,7 +820,7 @@ static ssize_t macvtap_put_user(struct m
 
 	if (q->flags & IFF_VNET_HDR) {
 		struct virtio_net_hdr vnet_hdr;
-		vnet_hdr_len = q->vnet_hdr_sz;
+		vnet_hdr_len = READ_ONCE(q->vnet_hdr_sz);
 		if (iov_iter_count(iter) < vnet_hdr_len)
 			return -EINVAL;
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/net/phy/mdio-bcm-iproc.c linux-libre-4.10-rc8-gnu/drivers/net/phy/mdio-bcm-iproc.c
--- linux-libre-4.10-rc7-gnu/drivers/net/phy/mdio-bcm-iproc.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/net/phy/mdio-bcm-iproc.c	2017-02-12 16:03:20.000000000 -0500
@@ -81,8 +81,6 @@ static int iproc_mdio_read(struct mii_bu
 	if (rc)
 		return rc;
 
-	iproc_mdio_config_clk(priv->base);
-
 	/* Prepare the read operation */
 	cmd = (MII_DATA_TA_VAL << MII_DATA_TA_SHIFT) |
 		(reg << MII_DATA_RA_SHIFT) |
@@ -112,8 +110,6 @@ static int iproc_mdio_write(struct mii_b
 	if (rc)
 		return rc;
 
-	iproc_mdio_config_clk(priv->base);
-
 	/* Prepare the write operation */
 	cmd = (MII_DATA_TA_VAL << MII_DATA_TA_SHIFT) |
 		(reg << MII_DATA_RA_SHIFT) |
@@ -163,6 +159,8 @@ static int iproc_mdio_probe(struct platf
 	bus->read = iproc_mdio_read;
 	bus->write = iproc_mdio_write;
 
+	iproc_mdio_config_clk(priv->base);
+
 	rc = of_mdiobus_register(bus, pdev->dev.of_node);
 	if (rc) {
 		dev_err(&pdev->dev, "MDIO bus registration failed\n");
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/net/phy/phy_device.c linux-libre-4.10-rc8-gnu/drivers/net/phy/phy_device.c
--- linux-libre-4.10-rc7-gnu/drivers/net/phy/phy_device.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/net/phy/phy_device.c	2017-02-12 16:03:20.000000000 -0500
@@ -908,6 +908,7 @@ int phy_attach_direct(struct net_device
 	struct module *ndev_owner = dev->dev.parent->driver->owner;
 	struct mii_bus *bus = phydev->mdio.bus;
 	struct device *d = &phydev->mdio.dev;
+	bool using_genphy = false;
 	int err;
 
 	/* For Ethernet device drivers that register their own MDIO bus, we
@@ -933,12 +934,22 @@ int phy_attach_direct(struct net_device
 			d->driver =
 				&genphy_driver[GENPHY_DRV_1G].mdiodrv.driver;
 
+		using_genphy = true;
+	}
+
+	if (!try_module_get(d->driver->owner)) {
+		dev_err(&dev->dev, "failed to get the device driver module\n");
+		err = -EIO;
+		goto error_put_device;
+	}
+
+	if (using_genphy) {
 		err = d->driver->probe(d);
 		if (err >= 0)
 			err = device_bind_driver(d);
 
 		if (err)
-			goto error;
+			goto error_module_put;
 	}
 
 	if (phydev->attached_dev) {
@@ -975,7 +986,13 @@ int phy_attach_direct(struct net_device
 	return err;
 
 error:
+	/* phy_detach() does all of the cleanup below */
 	phy_detach(phydev);
+	return err;
+
+error_module_put:
+	module_put(d->driver->owner);
+error_put_device:
 	put_device(d);
 	if (ndev_owner != bus->owner)
 		module_put(bus->owner);
@@ -1039,6 +1056,8 @@ void phy_detach(struct phy_device *phyde
 
 	phy_led_triggers_unregister(phydev);
 
+	module_put(phydev->mdio.dev.driver->owner);
+
 	/* If the device had no specific driver before (i.e. - it
 	 * was using the generic driver), we unbind the device
 	 * from the generic driver so that there's a chance a
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/net/tun.c linux-libre-4.10-rc8-gnu/drivers/net/tun.c
--- linux-libre-4.10-rc7-gnu/drivers/net/tun.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/net/tun.c	2017-02-12 16:03:20.000000000 -0500
@@ -1170,9 +1170,11 @@ static ssize_t tun_get_user(struct tun_s
 	}
 
 	if (tun->flags & IFF_VNET_HDR) {
-		if (len < tun->vnet_hdr_sz)
+		int vnet_hdr_sz = READ_ONCE(tun->vnet_hdr_sz);
+
+		if (len < vnet_hdr_sz)
 			return -EINVAL;
-		len -= tun->vnet_hdr_sz;
+		len -= vnet_hdr_sz;
 
 		if (!copy_from_iter_full(&gso, sizeof(gso), from))
 			return -EFAULT;
@@ -1183,7 +1185,7 @@ static ssize_t tun_get_user(struct tun_s
 
 		if (tun16_to_cpu(tun, gso.hdr_len) > len)
 			return -EINVAL;
-		iov_iter_advance(from, tun->vnet_hdr_sz - sizeof(gso));
+		iov_iter_advance(from, vnet_hdr_sz - sizeof(gso));
 	}
 
 	if ((tun->flags & TUN_TYPE_MASK) == IFF_TAP) {
@@ -1335,7 +1337,7 @@ static ssize_t tun_put_user(struct tun_s
 		vlan_hlen = VLAN_HLEN;
 
 	if (tun->flags & IFF_VNET_HDR)
-		vnet_hdr_sz = tun->vnet_hdr_sz;
+		vnet_hdr_sz = READ_ONCE(tun->vnet_hdr_sz);
 
 	total = skb->len + vlan_hlen + vnet_hdr_sz;
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/net/usb/catc.c linux-libre-4.10-rc8-gnu/drivers/net/usb/catc.c
--- linux-libre-4.10-rc7-gnu/drivers/net/usb/catc.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/net/usb/catc.c	2017-02-12 16:03:20.000000000 -0500
@@ -776,7 +776,7 @@ static int catc_probe(struct usb_interfa
 	struct net_device *netdev;
 	struct catc *catc;
 	u8 broadcast[ETH_ALEN];
-	int i, pktsz;
+	int pktsz, ret;
 
 	if (usb_set_interface(usbdev,
 			intf->altsetting->desc.bInterfaceNumber, 1)) {
@@ -811,12 +811,8 @@ static int catc_probe(struct usb_interfa
 	if ((!catc->ctrl_urb) || (!catc->tx_urb) || 
 	    (!catc->rx_urb) || (!catc->irq_urb)) {
 		dev_err(&intf->dev, "No free urbs available.\n");
-		usb_free_urb(catc->ctrl_urb);
-		usb_free_urb(catc->tx_urb);
-		usb_free_urb(catc->rx_urb);
-		usb_free_urb(catc->irq_urb);
-		free_netdev(netdev);
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto fail_free;
 	}
 
 	/* The F5U011 has the same vendor/product as the netmate but a device version of 0x130 */
@@ -844,15 +840,24 @@ static int catc_probe(struct usb_interfa
                 catc->irq_buf, 2, catc_irq_done, catc, 1);
 
 	if (!catc->is_f5u011) {
+		u32 *buf;
+		int i;
+
 		dev_dbg(dev, "Checking memory size\n");
 
-		i = 0x12345678;
-		catc_write_mem(catc, 0x7a80, &i, 4);
-		i = 0x87654321;	
-		catc_write_mem(catc, 0xfa80, &i, 4);
-		catc_read_mem(catc, 0x7a80, &i, 4);
+		buf = kmalloc(4, GFP_KERNEL);
+		if (!buf) {
+			ret = -ENOMEM;
+			goto fail_free;
+		}
+
+		*buf = 0x12345678;
+		catc_write_mem(catc, 0x7a80, buf, 4);
+		*buf = 0x87654321;
+		catc_write_mem(catc, 0xfa80, buf, 4);
+		catc_read_mem(catc, 0x7a80, buf, 4);
 	  
-		switch (i) {
+		switch (*buf) {
 		case 0x12345678:
 			catc_set_reg(catc, TxBufCount, 8);
 			catc_set_reg(catc, RxBufCount, 32);
@@ -867,6 +872,8 @@ static int catc_probe(struct usb_interfa
 			dev_dbg(dev, "32k Memory\n");
 			break;
 		}
+
+		kfree(buf);
 	  
 		dev_dbg(dev, "Getting MAC from SEEROM.\n");
 	  
@@ -913,16 +920,21 @@ static int catc_probe(struct usb_interfa
 	usb_set_intfdata(intf, catc);
 
 	SET_NETDEV_DEV(netdev, &intf->dev);
-	if (register_netdev(netdev) != 0) {
-		usb_set_intfdata(intf, NULL);
-		usb_free_urb(catc->ctrl_urb);
-		usb_free_urb(catc->tx_urb);
-		usb_free_urb(catc->rx_urb);
-		usb_free_urb(catc->irq_urb);
-		free_netdev(netdev);
-		return -EIO;
-	}
+	ret = register_netdev(netdev);
+	if (ret)
+		goto fail_clear_intfdata;
+
 	return 0;
+
+fail_clear_intfdata:
+	usb_set_intfdata(intf, NULL);
+fail_free:
+	usb_free_urb(catc->ctrl_urb);
+	usb_free_urb(catc->tx_urb);
+	usb_free_urb(catc->rx_urb);
+	usb_free_urb(catc->irq_urb);
+	free_netdev(netdev);
+	return ret;
 }
 
 static void catc_disconnect(struct usb_interface *intf)
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/net/usb/pegasus.c linux-libre-4.10-rc8-gnu/drivers/net/usb/pegasus.c
--- linux-libre-4.10-rc7-gnu/drivers/net/usb/pegasus.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/net/usb/pegasus.c	2017-02-12 16:03:20.000000000 -0500
@@ -126,40 +126,61 @@ static void async_ctrl_callback(struct u
 
 static int get_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data)
 {
+	u8 *buf;
 	int ret;
 
+	buf = kmalloc(size, GFP_NOIO);
+	if (!buf)
+		return -ENOMEM;
+
 	ret = usb_control_msg(pegasus->usb, usb_rcvctrlpipe(pegasus->usb, 0),
 			      PEGASUS_REQ_GET_REGS, PEGASUS_REQT_READ, 0,
-			      indx, data, size, 1000);
+			      indx, buf, size, 1000);
 	if (ret < 0)
 		netif_dbg(pegasus, drv, pegasus->net,
 			  "%s returned %d\n", __func__, ret);
+	else if (ret <= size)
+		memcpy(data, buf, ret);
+	kfree(buf);
 	return ret;
 }
 
-static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data)
+static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size,
+			 const void *data)
 {
+	u8 *buf;
 	int ret;
 
+	buf = kmemdup(data, size, GFP_NOIO);
+	if (!buf)
+		return -ENOMEM;
+
 	ret = usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0),
 			      PEGASUS_REQ_SET_REGS, PEGASUS_REQT_WRITE, 0,
-			      indx, data, size, 100);
+			      indx, buf, size, 100);
 	if (ret < 0)
 		netif_dbg(pegasus, drv, pegasus->net,
 			  "%s returned %d\n", __func__, ret);
+	kfree(buf);
 	return ret;
 }
 
 static int set_register(pegasus_t *pegasus, __u16 indx, __u8 data)
 {
+	u8 *buf;
 	int ret;
 
+	buf = kmemdup(&data, 1, GFP_NOIO);
+	if (!buf)
+		return -ENOMEM;
+
 	ret = usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0),
 			      PEGASUS_REQ_SET_REG, PEGASUS_REQT_WRITE, data,
-			      indx, &data, 1, 1000);
+			      indx, buf, 1, 1000);
 	if (ret < 0)
 		netif_dbg(pegasus, drv, pegasus->net,
 			  "%s returned %d\n", __func__, ret);
+	kfree(buf);
 	return ret;
 }
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/net/usb/rtl8150.c linux-libre-4.10-rc8-gnu/drivers/net/usb/rtl8150.c
--- linux-libre-4.10-rc7-gnu/drivers/net/usb/rtl8150.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/net/usb/rtl8150.c	2017-02-12 16:03:20.000000000 -0500
@@ -155,16 +155,36 @@ static const char driver_name [] = "rtl8
 */
 static int get_registers(rtl8150_t * dev, u16 indx, u16 size, void *data)
 {
-	return usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
-			       RTL8150_REQ_GET_REGS, RTL8150_REQT_READ,
-			       indx, 0, data, size, 500);
+	void *buf;
+	int ret;
+
+	buf = kmalloc(size, GFP_NOIO);
+	if (!buf)
+		return -ENOMEM;
+
+	ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
+			      RTL8150_REQ_GET_REGS, RTL8150_REQT_READ,
+			      indx, 0, buf, size, 500);
+	if (ret > 0 && ret <= size)
+		memcpy(data, buf, ret);
+	kfree(buf);
+	return ret;
 }
 
-static int set_registers(rtl8150_t * dev, u16 indx, u16 size, void *data)
+static int set_registers(rtl8150_t * dev, u16 indx, u16 size, const void *data)
 {
-	return usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
-			       RTL8150_REQ_SET_REGS, RTL8150_REQT_WRITE,
-			       indx, 0, data, size, 500);
+	void *buf;
+	int ret;
+
+	buf = kmemdup(data, size, GFP_NOIO);
+	if (!buf)
+		return -ENOMEM;
+
+	ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
+			      RTL8150_REQ_SET_REGS, RTL8150_REQT_WRITE,
+			      indx, 0, buf, size, 500);
+	kfree(buf);
+	return ret;
 }
 
 static void async_set_reg_cb(struct urb *urb)
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/net/usb/sierra_net.c linux-libre-4.10-rc8-gnu/drivers/net/usb/sierra_net.c
--- linux-libre-4.10-rc7-gnu/drivers/net/usb/sierra_net.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/net/usb/sierra_net.c	2017-02-12 16:03:20.000000000 -0500
@@ -73,8 +73,6 @@ static	atomic_t iface_counter = ATOMIC_I
 /* Private data structure */
 struct sierra_net_data {
 
-	u8 ethr_hdr_tmpl[ETH_HLEN]; /* ethernet header template for rx'd pkts */
-
 	u16 link_up;		/* air link up or down */
 	u8 tx_hdr_template[4];	/* part of HIP hdr for tx'd packets */
 
@@ -122,6 +120,7 @@ struct param {
 
 /* LSI Protocol types */
 #define SIERRA_NET_PROTOCOL_UMTS      0x01
+#define SIERRA_NET_PROTOCOL_UMTS_DS   0x04
 /* LSI Coverage */
 #define SIERRA_NET_COVERAGE_NONE      0x00
 #define SIERRA_NET_COVERAGE_NOPACKET  0x01
@@ -129,7 +128,8 @@ struct param {
 /* LSI Session */
 #define SIERRA_NET_SESSION_IDLE       0x00
 /* LSI Link types */
-#define SIERRA_NET_AS_LINK_TYPE_IPv4  0x00
+#define SIERRA_NET_AS_LINK_TYPE_IPV4  0x00
+#define SIERRA_NET_AS_LINK_TYPE_IPV6  0x02
 
 struct lsi_umts {
 	u8 protocol;
@@ -137,9 +137,14 @@ struct lsi_umts {
 	__be16 length;
 	/* eventually use a union for the rest - assume umts for now */
 	u8 coverage;
-	u8 unused2[41];
+	u8 network_len; /* network name len */
+	u8 network[40]; /* network name (UCS2, bigendian) */
 	u8 session_state;
 	u8 unused3[33];
+} __packed;
+
+struct lsi_umts_single {
+	struct lsi_umts lsi;
 	u8 link_type;
 	u8 pdp_addr_len; /* NW-supplied PDP address len */
 	u8 pdp_addr[16]; /* NW-supplied PDP address (bigendian)) */
@@ -158,10 +163,31 @@ struct lsi_umts {
 	u8 reserved[8];
 } __packed;
 
+struct lsi_umts_dual {
+	struct lsi_umts lsi;
+	u8 pdp_addr4_len; /* NW-supplied PDP IPv4 address len */
+	u8 pdp_addr4[4];  /* NW-supplied PDP IPv4 address (bigendian)) */
+	u8 pdp_addr6_len; /* NW-supplied PDP IPv6 address len */
+	u8 pdp_addr6[16]; /* NW-supplied PDP IPv6 address (bigendian)) */
+	u8 unused4[23];
+	u8 dns1_addr4_len; /* NW-supplied 1st DNS v4 address len (bigendian) */
+	u8 dns1_addr4[4];  /* NW-supplied 1st DNS v4 address */
+	u8 dns1_addr6_len; /* NW-supplied 1st DNS v6 address len */
+	u8 dns1_addr6[16]; /* NW-supplied 1st DNS v6 address (bigendian)*/
+	u8 dns2_addr4_len; /* NW-supplied 2nd DNS v4 address len (bigendian) */
+	u8 dns2_addr4[4];  /* NW-supplied 2nd DNS v4 address */
+	u8 dns2_addr6_len; /* NW-supplied 2nd DNS v6 address len */
+	u8 dns2_addr6[16]; /* NW-supplied 2nd DNS v6 address (bigendian)*/
+	u8 unused5[68];
+} __packed;
+
 #define SIERRA_NET_LSI_COMMON_LEN      4
-#define SIERRA_NET_LSI_UMTS_LEN        (sizeof(struct lsi_umts))
+#define SIERRA_NET_LSI_UMTS_LEN        (sizeof(struct lsi_umts_single))
 #define SIERRA_NET_LSI_UMTS_STATUS_LEN \
 	(SIERRA_NET_LSI_UMTS_LEN - SIERRA_NET_LSI_COMMON_LEN)
+#define SIERRA_NET_LSI_UMTS_DS_LEN     (sizeof(struct lsi_umts_dual))
+#define SIERRA_NET_LSI_UMTS_DS_STATUS_LEN \
+	(SIERRA_NET_LSI_UMTS_DS_LEN - SIERRA_NET_LSI_COMMON_LEN)
 
 /* Forward definitions */
 static void sierra_sync_timer(unsigned long syncdata);
@@ -190,10 +216,11 @@ static inline void sierra_net_set_privat
 	dev->data[0] = (unsigned long)priv;
 }
 
-/* is packet IPv4 */
+/* is packet IPv4/IPv6 */
 static inline int is_ip(struct sk_buff *skb)
 {
-	return skb->protocol == cpu_to_be16(ETH_P_IP);
+	return skb->protocol == cpu_to_be16(ETH_P_IP) ||
+	       skb->protocol == cpu_to_be16(ETH_P_IPV6);
 }
 
 /*
@@ -349,49 +376,54 @@ static inline int sierra_net_is_valid_ad
 static int sierra_net_parse_lsi(struct usbnet *dev, char *data, int datalen)
 {
 	struct lsi_umts *lsi = (struct lsi_umts *)data;
+	u32 expected_length;
 
-	if (datalen < sizeof(struct lsi_umts)) {
-		netdev_err(dev->net, "%s: Data length %d, exp %Zu\n",
-				__func__, datalen,
-				sizeof(struct lsi_umts));
+	if (datalen < sizeof(struct lsi_umts_single)) {
+		netdev_err(dev->net, "%s: Data length %d, exp >= %Zu\n",
+			   __func__, datalen, sizeof(struct lsi_umts_single));
 		return -1;
 	}
 
-	if (lsi->length != cpu_to_be16(SIERRA_NET_LSI_UMTS_STATUS_LEN)) {
-		netdev_err(dev->net, "%s: LSI_UMTS_STATUS_LEN %d, exp %u\n",
-				__func__, be16_to_cpu(lsi->length),
-				(u32)SIERRA_NET_LSI_UMTS_STATUS_LEN);
-		return -1;
+	/* Validate the session state */
+	if (lsi->session_state == SIERRA_NET_SESSION_IDLE) {
+		netdev_err(dev->net, "Session idle, 0x%02x\n",
+			   lsi->session_state);
+		return 0;
 	}
 
 	/* Validate the protocol  - only support UMTS for now */
-	if (lsi->protocol != SIERRA_NET_PROTOCOL_UMTS) {
+	if (lsi->protocol == SIERRA_NET_PROTOCOL_UMTS) {
+		struct lsi_umts_single *single = (struct lsi_umts_single *)lsi;
+
+		/* Validate the link type */
+		if (single->link_type != SIERRA_NET_AS_LINK_TYPE_IPV4 &&
+		    single->link_type != SIERRA_NET_AS_LINK_TYPE_IPV6) {
+			netdev_err(dev->net, "Link type unsupported: 0x%02x\n",
+				   single->link_type);
+			return -1;
+		}
+		expected_length = SIERRA_NET_LSI_UMTS_STATUS_LEN;
+	} else if (lsi->protocol == SIERRA_NET_PROTOCOL_UMTS_DS) {
+		expected_length = SIERRA_NET_LSI_UMTS_DS_STATUS_LEN;
+	} else {
 		netdev_err(dev->net, "Protocol unsupported, 0x%02x\n",
-			lsi->protocol);
+			   lsi->protocol);
 		return -1;
 	}
 
-	/* Validate the link type */
-	if (lsi->link_type != SIERRA_NET_AS_LINK_TYPE_IPv4) {
-		netdev_err(dev->net, "Link type unsupported: 0x%02x\n",
-			lsi->link_type);
+	if (be16_to_cpu(lsi->length) != expected_length) {
+		netdev_err(dev->net, "%s: LSI_UMTS_STATUS_LEN %d, exp %u\n",
+			   __func__, be16_to_cpu(lsi->length), expected_length);
 		return -1;
 	}
 
 	/* Validate the coverage */
-	if (lsi->coverage == SIERRA_NET_COVERAGE_NONE
-	   || lsi->coverage == SIERRA_NET_COVERAGE_NOPACKET) {
+	if (lsi->coverage == SIERRA_NET_COVERAGE_NONE ||
+	    lsi->coverage == SIERRA_NET_COVERAGE_NOPACKET) {
 		netdev_err(dev->net, "No coverage, 0x%02x\n", lsi->coverage);
 		return 0;
 	}
 
-	/* Validate the session state */
-	if (lsi->session_state == SIERRA_NET_SESSION_IDLE) {
-		netdev_err(dev->net, "Session idle, 0x%02x\n",
-			lsi->session_state);
-		return 0;
-	}
-
 	/* Set link_sense true */
 	return 1;
 }
@@ -652,7 +684,6 @@ static int sierra_net_bind(struct usbnet
 	u8	numendpoints;
 	u16	fwattr = 0;
 	int	status;
-	struct ethhdr *eth;
 	struct sierra_net_data *priv;
 	static const u8 sync_tmplate[sizeof(priv->sync_msg)] = {
 		0x00, 0x00, SIERRA_NET_HIP_MSYNC_ID, 0x00};
@@ -690,11 +721,6 @@ static int sierra_net_bind(struct usbnet
 	dev->net->dev_addr[ETH_ALEN-2] = atomic_inc_return(&iface_counter);
 	dev->net->dev_addr[ETH_ALEN-1] = ifacenum;
 
-	/* we will have to manufacture ethernet headers, prepare template */
-	eth = (struct ethhdr *)priv->ethr_hdr_tmpl;
-	memcpy(&eth->h_dest, dev->net->dev_addr, ETH_ALEN);
-	eth->h_proto = cpu_to_be16(ETH_P_IP);
-
 	/* prepare shutdown message template */
 	memcpy(priv->shdwn_msg, shdwn_tmplate, sizeof(priv->shdwn_msg));
 	/* set context index initially to 0 - prepares tx hdr template */
@@ -824,9 +850,14 @@ static int sierra_net_rx_fixup(struct us
 
 		skb_pull(skb, hh.hdrlen);
 
-		/* We are going to accept this packet, prepare it */
-		memcpy(skb->data, sierra_net_get_private(dev)->ethr_hdr_tmpl,
-			ETH_HLEN);
+		/* We are going to accept this packet, prepare it.
+		 * In case protocol is IPv6, keep it, otherwise force IPv4.
+		 */
+		skb_reset_mac_header(skb);
+		if (eth_hdr(skb)->h_proto != cpu_to_be16(ETH_P_IPV6))
+			eth_hdr(skb)->h_proto = cpu_to_be16(ETH_P_IP);
+		eth_zero_addr(eth_hdr(skb)->h_source);
+		memcpy(eth_hdr(skb)->h_dest, dev->net->dev_addr, ETH_ALEN);
 
 		/* Last packet in batch handled by usbnet */
 		if (hh.payload_len.word == skb->len)
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c linux-libre-4.10-rc8-gnu/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c
--- linux-libre-4.10-rc7-gnu/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c	2017-02-06 11:02:50.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c	2017-02-12 17:46:41.000000000 -0500
@@ -92,7 +92,7 @@ int rtl92c_init_sw_vars(struct ieee80211
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
-	char *fw_name = "/*(DEBLOBBED)*/";
+	char *fw_name;
 
 	rtl8192ce_bt_reg_init(hw);
 
@@ -164,7 +164,12 @@ int rtl92c_init_sw_vars(struct ieee80211
 	}
 
 	/* request fw */
-	if (IS_81XXC_VENDOR_UMC_B_CUT(rtlhal->version))
+	if (IS_VENDOR_UMC_A_CUT(rtlhal->version) &&
+	    !IS_92C_SERIAL(rtlhal->version))
+		fw_name = "/*(DEBLOBBED)*/";
+	else if (IS_81XXC_VENDOR_UMC_B_CUT(rtlhal->version))
+		fw_name = "/*(DEBLOBBED)*/";
+	else
 		fw_name = "/*(DEBLOBBED)*/";
 
 	rtlpriv->max_fw_size = 0x4000;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/net/xen-netfront.c linux-libre-4.10-rc8-gnu/drivers/net/xen-netfront.c
--- linux-libre-4.10-rc7-gnu/drivers/net/xen-netfront.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/net/xen-netfront.c	2017-02-12 16:03:20.000000000 -0500
@@ -281,6 +281,7 @@ static void xennet_alloc_rx_buffers(stru
 {
 	RING_IDX req_prod = queue->rx.req_prod_pvt;
 	int notify;
+	int err = 0;
 
 	if (unlikely(!netif_carrier_ok(queue->info->netdev)))
 		return;
@@ -295,8 +296,10 @@ static void xennet_alloc_rx_buffers(stru
 		struct xen_netif_rx_request *req;
 
 		skb = xennet_alloc_one_rx_buffer(queue);
-		if (!skb)
+		if (!skb) {
+			err = -ENOMEM;
 			break;
+		}
 
 		id = xennet_rxidx(req_prod);
 
@@ -320,8 +323,13 @@ static void xennet_alloc_rx_buffers(stru
 
 	queue->rx.req_prod_pvt = req_prod;
 
-	/* Not enough requests? Try again later. */
-	if (req_prod - queue->rx.sring->req_prod < NET_RX_SLOTS_MIN) {
+	/* Try again later if there are not enough requests or skb allocation
+	 * failed.
+	 * Enough requests is quantified as the sum of newly created slots and
+	 * the unconsumed slots at the backend.
+	 */
+	if (req_prod - queue->rx.rsp_cons < NET_RX_SLOTS_MIN ||
+	    unlikely(err)) {
 		mod_timer(&queue->rx_refill_timer, jiffies + (HZ/10));
 		return;
 	}
@@ -1379,6 +1387,8 @@ static void xennet_disconnect_backend(st
 	for (i = 0; i < num_queues && info->queues; ++i) {
 		struct netfront_queue *queue = &info->queues[i];
 
+		del_timer_sync(&queue->rx_refill_timer);
+
 		if (queue->tx_irq && (queue->tx_irq == queue->rx_irq))
 			unbind_from_irqhandler(queue->tx_irq, queue);
 		if (queue->tx_irq && (queue->tx_irq != queue->rx_irq)) {
@@ -1733,7 +1743,6 @@ static void xennet_destroy_queues(struct
 
 		if (netif_running(info->netdev))
 			napi_disable(&queue->napi);
-		del_timer_sync(&queue->rx_refill_timer);
 		netif_napi_del(&queue->napi);
 	}
 
@@ -1822,27 +1831,19 @@ static int talk_to_netback(struct xenbus
 		xennet_destroy_queues(info);
 
 	err = xennet_create_queues(info, &num_queues);
-	if (err < 0)
-		goto destroy_ring;
+	if (err < 0) {
+		xenbus_dev_fatal(dev, err, "creating queues");
+		kfree(info->queues);
+		info->queues = NULL;
+		goto out;
+	}
 
 	/* Create shared ring, alloc event channel -- for each queue */
 	for (i = 0; i < num_queues; ++i) {
 		queue = &info->queues[i];
 		err = setup_netfront(dev, queue, feature_split_evtchn);
-		if (err) {
-			/* setup_netfront() will tidy up the current
-			 * queue on error, but we need to clean up
-			 * those already allocated.
-			 */
-			if (i > 0) {
-				rtnl_lock();
-				netif_set_real_num_tx_queues(info->netdev, i);
-				rtnl_unlock();
-				goto destroy_ring;
-			} else {
-				goto out;
-			}
-		}
+		if (err)
+			goto destroy_ring;
 	}
 
 again:
@@ -1932,9 +1933,10 @@ abort_transaction_no_dev_fatal:
 	xenbus_transaction_end(xbt, 1);
  destroy_ring:
 	xennet_disconnect_backend(info);
-	kfree(info->queues);
-	info->queues = NULL;
+	xennet_destroy_queues(info);
  out:
+	unregister_netdev(info->netdev);
+	xennet_free_netdev(info->netdev);
 	return err;
 }
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/nvdimm/namespace_devs.c linux-libre-4.10-rc8-gnu/drivers/nvdimm/namespace_devs.c
--- linux-libre-4.10-rc7-gnu/drivers/nvdimm/namespace_devs.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/nvdimm/namespace_devs.c	2017-02-12 16:03:20.000000000 -0500
@@ -52,17 +52,17 @@ static void namespace_blk_release(struct
 	kfree(nsblk);
 }
 
-static struct device_type namespace_io_device_type = {
+static const struct device_type namespace_io_device_type = {
 	.name = "nd_namespace_io",
 	.release = namespace_io_release,
 };
 
-static struct device_type namespace_pmem_device_type = {
+static const struct device_type namespace_pmem_device_type = {
 	.name = "nd_namespace_pmem",
 	.release = namespace_pmem_release,
 };
 
-static struct device_type namespace_blk_device_type = {
+static const struct device_type namespace_blk_device_type = {
 	.name = "nd_namespace_blk",
 	.release = namespace_blk_release,
 };
@@ -962,8 +962,8 @@ static ssize_t __size_store(struct devic
 	struct nvdimm_drvdata *ndd;
 	struct nd_label_id label_id;
 	u32 flags = 0, remainder;
+	int rc, i, id = -1;
 	u8 *uuid = NULL;
-	int rc, i;
 
 	if (dev->driver || ndns->claim)
 		return -EBUSY;
@@ -972,11 +972,13 @@ static ssize_t __size_store(struct devic
 		struct nd_namespace_pmem *nspm = to_nd_namespace_pmem(dev);
 
 		uuid = nspm->uuid;
+		id = nspm->id;
 	} else if (is_namespace_blk(dev)) {
 		struct nd_namespace_blk *nsblk = to_nd_namespace_blk(dev);
 
 		uuid = nsblk->uuid;
 		flags = NSLABEL_FLAG_LOCAL;
+		id = nsblk->id;
 	}
 
 	/*
@@ -1039,10 +1041,11 @@ static ssize_t __size_store(struct devic
 
 	/*
 	 * Try to delete the namespace if we deleted all of its
-	 * allocation, this is not the seed device for the region, and
-	 * it is not actively claimed by a btt instance.
+	 * allocation, this is not the seed or 0th device for the
+	 * region, and it is not actively claimed by a btt, pfn, or dax
+	 * instance.
 	 */
-	if (val == 0 && nd_region->ns_seed != dev && !ndns->claim)
+	if (val == 0 && id != 0 && nd_region->ns_seed != dev && !ndns->claim)
 		nd_device_unregister(dev, ND_ASYNC);
 
 	return rc;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/nvdimm/pfn_devs.c linux-libre-4.10-rc8-gnu/drivers/nvdimm/pfn_devs.c
--- linux-libre-4.10-rc7-gnu/drivers/nvdimm/pfn_devs.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/nvdimm/pfn_devs.c	2017-02-12 16:03:20.000000000 -0500
@@ -627,15 +627,12 @@ static int nd_pfn_init(struct nd_pfn *nd
 	size = resource_size(&nsio->res);
 	npfns = (size - start_pad - end_trunc - SZ_8K) / SZ_4K;
 	if (nd_pfn->mode == PFN_MODE_PMEM) {
-		unsigned long memmap_size;
-
 		/*
 		 * vmemmap_populate_hugepages() allocates the memmap array in
 		 * HPAGE_SIZE chunks.
 		 */
-		memmap_size = ALIGN(64 * npfns, HPAGE_SIZE);
-		offset = ALIGN(start + SZ_8K + memmap_size + dax_label_reserve,
-				nd_pfn->align) - start;
+		offset = ALIGN(start + SZ_8K + 64 * npfns + dax_label_reserve,
+				max(nd_pfn->align, HPAGE_SIZE)) - start;
 	} else if (nd_pfn->mode == PFN_MODE_RAM)
 		offset = ALIGN(start + SZ_8K + dax_label_reserve,
 				nd_pfn->align) - start;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/pci/hotplug/pciehp_ctrl.c linux-libre-4.10-rc8-gnu/drivers/pci/hotplug/pciehp_ctrl.c
--- linux-libre-4.10-rc7-gnu/drivers/pci/hotplug/pciehp_ctrl.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/pci/hotplug/pciehp_ctrl.c	2017-02-12 16:03:20.000000000 -0500
@@ -31,7 +31,6 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/slab.h>
-#include <linux/pm_runtime.h>
 #include <linux/pci.h>
 #include "../pci.h"
 #include "pciehp.h"
@@ -99,7 +98,6 @@ static int board_added(struct slot *p_sl
 	pciehp_green_led_blink(p_slot);
 
 	/* Check link training status */
-	pm_runtime_get_sync(&ctrl->pcie->port->dev);
 	retval = pciehp_check_link_status(ctrl);
 	if (retval) {
 		ctrl_err(ctrl, "Failed to check link status\n");
@@ -120,14 +118,12 @@ static int board_added(struct slot *p_sl
 		if (retval != -EEXIST)
 			goto err_exit;
 	}
-	pm_runtime_put(&ctrl->pcie->port->dev);
 
 	pciehp_green_led_on(p_slot);
 	pciehp_set_attention_status(p_slot, 0);
 	return 0;
 
 err_exit:
-	pm_runtime_put(&ctrl->pcie->port->dev);
 	set_slot_off(ctrl, p_slot);
 	return retval;
 }
@@ -141,9 +137,7 @@ static int remove_board(struct slot *p_s
 	int retval;
 	struct controller *ctrl = p_slot->ctrl;
 
-	pm_runtime_get_sync(&ctrl->pcie->port->dev);
 	retval = pciehp_unconfigure_device(p_slot);
-	pm_runtime_put(&ctrl->pcie->port->dev);
 	if (retval)
 		return retval;
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/pci/msi.c linux-libre-4.10-rc8-gnu/drivers/pci/msi.c
--- linux-libre-4.10-rc7-gnu/drivers/pci/msi.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/pci/msi.c	2017-02-12 16:03:20.000000000 -0500
@@ -1206,6 +1206,16 @@ int pci_alloc_irq_vectors_affinity(struc
 	if (flags & PCI_IRQ_AFFINITY) {
 		if (!affd)
 			affd = &msi_default_affd;
+
+		if (affd->pre_vectors + affd->post_vectors > min_vecs)
+			return -EINVAL;
+
+		/*
+		 * If there aren't any vectors left after applying the pre/post
+		 * vectors don't bother with assigning affinity.
+		 */
+		if (affd->pre_vectors + affd->post_vectors == min_vecs)
+			affd = NULL;
 	} else {
 		if (WARN_ON(affd))
 			affd = NULL;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/pci/pci.c linux-libre-4.10-rc8-gnu/drivers/pci/pci.c
--- linux-libre-4.10-rc7-gnu/drivers/pci/pci.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/pci/pci.c	2017-02-12 16:03:20.000000000 -0500
@@ -2241,10 +2241,13 @@ bool pci_bridge_d3_possible(struct pci_d
 			return false;
 
 		/*
-		 * Hotplug ports handled by firmware in System Management Mode
+		 * Hotplug interrupts cannot be delivered if the link is down,
+		 * so parents of a hotplug port must stay awake. In addition,
+		 * hotplug ports handled by firmware in System Management Mode
 		 * may not be put into D3 by the OS (Thunderbolt on non-Macs).
+		 * For simplicity, disallow in general for now.
 		 */
-		if (bridge->is_hotplug_bridge && !pciehp_is_native(bridge))
+		if (bridge->is_hotplug_bridge)
 			return false;
 
 		if (pci_bridge_d3_force)
@@ -2276,10 +2279,7 @@ static int pci_dev_check_d3cold(struct p
 	     !pci_pme_capable(dev, PCI_D3cold)) ||
 
 	    /* If it is a bridge it must be allowed to go to D3. */
-	    !pci_power_manageable(dev) ||
-
-	    /* Hotplug interrupts cannot be delivered if the link is down. */
-	    dev->is_hotplug_bridge)
+	    !pci_power_manageable(dev))
 
 		*d3cold_ok = false;
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/s390/scsi/zfcp_fsf.c linux-libre-4.10-rc8-gnu/drivers/s390/scsi/zfcp_fsf.c
--- linux-libre-4.10-rc7-gnu/drivers/s390/scsi/zfcp_fsf.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/s390/scsi/zfcp_fsf.c	2017-02-12 16:03:20.000000000 -0500
@@ -1583,7 +1583,7 @@ out:
 int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port)
 {
 	struct zfcp_qdio *qdio = wka_port->adapter->qdio;
-	struct zfcp_fsf_req *req = NULL;
+	struct zfcp_fsf_req *req;
 	int retval = -EIO;
 
 	spin_lock_irq(&qdio->req_q_lock);
@@ -1612,7 +1612,7 @@ int zfcp_fsf_open_wka_port(struct zfcp_f
 		zfcp_fsf_req_free(req);
 out:
 	spin_unlock_irq(&qdio->req_q_lock);
-	if (req && !IS_ERR(req))
+	if (!retval)
 		zfcp_dbf_rec_run_wka("fsowp_1", wka_port, req->req_id);
 	return retval;
 }
@@ -1638,7 +1638,7 @@ static void zfcp_fsf_close_wka_port_hand
 int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port)
 {
 	struct zfcp_qdio *qdio = wka_port->adapter->qdio;
-	struct zfcp_fsf_req *req = NULL;
+	struct zfcp_fsf_req *req;
 	int retval = -EIO;
 
 	spin_lock_irq(&qdio->req_q_lock);
@@ -1667,7 +1667,7 @@ int zfcp_fsf_close_wka_port(struct zfcp_
 		zfcp_fsf_req_free(req);
 out:
 	spin_unlock_irq(&qdio->req_q_lock);
-	if (req && !IS_ERR(req))
+	if (!retval)
 		zfcp_dbf_rec_run_wka("fscwp_1", wka_port, req->req_id);
 	return retval;
 }
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/scsi/aacraid/comminit.c linux-libre-4.10-rc8-gnu/drivers/scsi/aacraid/comminit.c
--- linux-libre-4.10-rc7-gnu/drivers/scsi/aacraid/comminit.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/scsi/aacraid/comminit.c	2017-02-12 16:03:20.000000000 -0500
@@ -50,9 +50,13 @@ struct aac_common aac_config = {
 
 static inline int aac_is_msix_mode(struct aac_dev *dev)
 {
-	u32 status;
+	u32 status = 0;
 
-	status = src_readl(dev, MUnit.OMR);
+	if (dev->pdev->device == PMC_DEVICE_S6 ||
+		dev->pdev->device == PMC_DEVICE_S7 ||
+		dev->pdev->device == PMC_DEVICE_S8) {
+		status = src_readl(dev, MUnit.OMR);
+	}
 	return (status & AAC_INT_MODE_MSIX);
 }
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c linux-libre-4.10-rc8-gnu/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
--- linux-libre-4.10-rc7-gnu/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c	2017-02-12 16:03:20.000000000 -0500
@@ -3816,6 +3816,7 @@ static struct configfs_attribute *ibmvsc
 static const struct target_core_fabric_ops ibmvscsis_ops = {
 	.module				= THIS_MODULE,
 	.name				= "ibmvscsis",
+	.max_data_sg_nents		= MAX_TXU / PAGE_SIZE,
 	.get_fabric_name		= ibmvscsis_get_fabric_name,
 	.tpg_get_wwn			= ibmvscsis_get_fabric_wwn,
 	.tpg_get_tag			= ibmvscsis_get_tag,
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/scsi/mpt3sas/mpt3sas_scsih.c linux-libre-4.10-rc8-gnu/drivers/scsi/mpt3sas/mpt3sas_scsih.c
--- linux-libre-4.10-rc7-gnu/drivers/scsi/mpt3sas/mpt3sas_scsih.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/scsi/mpt3sas/mpt3sas_scsih.c	2017-02-12 16:03:20.000000000 -0500
@@ -51,6 +51,7 @@
 #include <linux/workqueue.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
+#include <linux/pci-aspm.h>
 #include <linux/interrupt.h>
 #include <linux/aer.h>
 #include <linux/raid_class.h>
@@ -4657,6 +4658,7 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *i
 	struct MPT3SAS_DEVICE *sas_device_priv_data;
 	u32 response_code = 0;
 	unsigned long flags;
+	unsigned int sector_sz;
 
 	mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply);
 	scmd = _scsih_scsi_lookup_get_clear(ioc, smid);
@@ -4715,6 +4717,20 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *i
 	}
 
 	xfer_cnt = le32_to_cpu(mpi_reply->TransferCount);
+
+	/* In case of bogus fw or device, we could end up having
+	 * unaligned partial completion. We can force alignment here,
+	 * then scsi-ml does not need to handle this misbehavior.
+	 */
+	sector_sz = scmd->device->sector_size;
+	if (unlikely(scmd->request->cmd_type == REQ_TYPE_FS && sector_sz &&
+		     xfer_cnt % sector_sz)) {
+		sdev_printk(KERN_INFO, scmd->device,
+		    "unaligned partial completion avoided (xfer_cnt=%u, sector_sz=%u)\n",
+			    xfer_cnt, sector_sz);
+		xfer_cnt = round_down(xfer_cnt, sector_sz);
+	}
+
 	scsi_set_resid(scmd, scsi_bufflen(scmd) - xfer_cnt);
 	if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE)
 		log_info =  le32_to_cpu(mpi_reply->IOCLogInfo);
@@ -8746,6 +8762,8 @@ _scsih_probe(struct pci_dev *pdev, const
 
 	switch (hba_mpi_version) {
 	case MPI2_VERSION:
+		pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S |
+			PCIE_LINK_STATE_L1 | PCIE_LINK_STATE_CLKPM);
 		/* Use mpt2sas driver host template for SAS 2.0 HBA's */
 		shost = scsi_host_alloc(&mpt2sas_driver_template,
 		  sizeof(struct MPT3SAS_ADAPTER));
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/scsi/qla2xxx/qla_isr.c linux-libre-4.10-rc8-gnu/drivers/scsi/qla2xxx/qla_isr.c
--- linux-libre-4.10-rc7-gnu/drivers/scsi/qla2xxx/qla_isr.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/scsi/qla2xxx/qla_isr.c	2017-02-12 16:03:20.000000000 -0500
@@ -3242,7 +3242,7 @@ qla2x00_free_irqs(scsi_qla_host_t *vha)
 	 * from a probe failure context.
 	 */
 	if (!ha->rsp_q_map || !ha->rsp_q_map[0])
-		return;
+		goto free_irqs;
 	rsp = ha->rsp_q_map[0];
 
 	if (ha->flags.msix_enabled) {
@@ -3262,6 +3262,7 @@ qla2x00_free_irqs(scsi_qla_host_t *vha)
 		free_irq(pci_irq_vector(ha->pdev, 0), rsp);
 	}
 
+free_irqs:
 	pci_free_irq_vectors(ha->pdev);
 }
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/scsi/qla2xxx/qla_os.c linux-libre-4.10-rc8-gnu/drivers/scsi/qla2xxx/qla_os.c
--- linux-libre-4.10-rc7-gnu/drivers/scsi/qla2xxx/qla_os.c	2017-02-06 11:06:45.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/scsi/qla2xxx/qla_os.c	2017-02-12 17:51:57.000000000 -0500
@@ -1616,7 +1616,7 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *
 				/* Don't abort commands in adapter during EEH
 				 * recovery as it's not accessible/responding.
 				 */
-				if (!ha->flags.eeh_busy) {
+				if (GET_CMD_SP(sp) && !ha->flags.eeh_busy) {
 					/* Get a reference to the sp and drop the lock.
 					 * The reference ensures this sp->done() call
 					 * - and not the call in qla2xxx_eh_abort() -
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/staging/lustre/lustre/llite/llite_mmap.c linux-libre-4.10-rc8-gnu/drivers/staging/lustre/lustre/llite/llite_mmap.c
--- linux-libre-4.10-rc7-gnu/drivers/staging/lustre/lustre/llite/llite_mmap.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/staging/lustre/lustre/llite/llite_mmap.c	2017-02-12 16:03:20.000000000 -0500
@@ -390,15 +390,13 @@ static int ll_page_mkwrite(struct vm_are
 		result = VM_FAULT_LOCKED;
 		break;
 	case -ENODATA:
+	case -EAGAIN:
 	case -EFAULT:
 		result = VM_FAULT_NOPAGE;
 		break;
 	case -ENOMEM:
 		result = VM_FAULT_OOM;
 		break;
-	case -EAGAIN:
-		result = VM_FAULT_RETRY;
-		break;
 	default:
 		result = VM_FAULT_SIGBUS;
 		break;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/target/target_core_device.c linux-libre-4.10-rc8-gnu/drivers/target/target_core_device.c
--- linux-libre-4.10-rc7-gnu/drivers/target/target_core_device.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/target/target_core_device.c	2017-02-12 16:03:20.000000000 -0500
@@ -352,7 +352,15 @@ int core_enable_device_list_for_node(
 			kfree(new);
 			return -EINVAL;
 		}
-		BUG_ON(orig->se_lun_acl != NULL);
+		if (orig->se_lun_acl != NULL) {
+			pr_warn_ratelimited("Detected existing explicit"
+				" se_lun_acl->se_lun_group reference for %s"
+				" mapped_lun: %llu, failing\n",
+				 nacl->initiatorname, mapped_lun);
+			mutex_unlock(&nacl->lun_entry_mutex);
+			kfree(new);
+			return -EINVAL;
+		}
 
 		rcu_assign_pointer(new->se_lun, lun);
 		rcu_assign_pointer(new->se_lun_acl, lun_acl);
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/target/target_core_sbc.c linux-libre-4.10-rc8-gnu/drivers/target/target_core_sbc.c
--- linux-libre-4.10-rc7-gnu/drivers/target/target_core_sbc.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/target/target_core_sbc.c	2017-02-12 16:03:20.000000000 -0500
@@ -451,6 +451,7 @@ static sense_reason_t compare_and_write_
 					     int *post_ret)
 {
 	struct se_device *dev = cmd->se_dev;
+	sense_reason_t ret = TCM_NO_SENSE;
 
 	/*
 	 * Only set SCF_COMPARE_AND_WRITE_POST to force a response fall-through
@@ -458,9 +459,12 @@ static sense_reason_t compare_and_write_
 	 * sent to the backend driver.
 	 */
 	spin_lock_irq(&cmd->t_state_lock);
-	if ((cmd->transport_state & CMD_T_SENT) && !cmd->scsi_status) {
+	if (cmd->transport_state & CMD_T_SENT) {
 		cmd->se_cmd_flags |= SCF_COMPARE_AND_WRITE_POST;
 		*post_ret = 1;
+
+		if (cmd->scsi_status == SAM_STAT_CHECK_CONDITION)
+			ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
 	}
 	spin_unlock_irq(&cmd->t_state_lock);
 
@@ -470,7 +474,7 @@ static sense_reason_t compare_and_write_
 	 */
 	up(&dev->caw_sem);
 
-	return TCM_NO_SENSE;
+	return ret;
 }
 
 static sense_reason_t compare_and_write_callback(struct se_cmd *cmd, bool success,
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/target/target_core_transport.c linux-libre-4.10-rc8-gnu/drivers/target/target_core_transport.c
--- linux-libre-4.10-rc7-gnu/drivers/target/target_core_transport.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/target/target_core_transport.c	2017-02-12 16:03:20.000000000 -0500
@@ -457,8 +457,20 @@ static void target_complete_nacl(struct
 {
 	struct se_node_acl *nacl = container_of(kref,
 				struct se_node_acl, acl_kref);
+	struct se_portal_group *se_tpg = nacl->se_tpg;
 
-	complete(&nacl->acl_free_comp);
+	if (!nacl->dynamic_stop) {
+		complete(&nacl->acl_free_comp);
+		return;
+	}
+
+	mutex_lock(&se_tpg->acl_node_mutex);
+	list_del(&nacl->acl_list);
+	mutex_unlock(&se_tpg->acl_node_mutex);
+
+	core_tpg_wait_for_nacl_pr_ref(nacl);
+	core_free_device_list_for_node(nacl, se_tpg);
+	kfree(nacl);
 }
 
 void target_put_nacl(struct se_node_acl *nacl)
@@ -499,12 +511,39 @@ EXPORT_SYMBOL(transport_deregister_sessi
 void transport_free_session(struct se_session *se_sess)
 {
 	struct se_node_acl *se_nacl = se_sess->se_node_acl;
+
 	/*
 	 * Drop the se_node_acl->nacl_kref obtained from within
 	 * core_tpg_get_initiator_node_acl().
 	 */
 	if (se_nacl) {
+		struct se_portal_group *se_tpg = se_nacl->se_tpg;
+		const struct target_core_fabric_ops *se_tfo = se_tpg->se_tpg_tfo;
+		unsigned long flags;
+
 		se_sess->se_node_acl = NULL;
+
+		/*
+		 * Also determine if we need to drop the extra ->cmd_kref if
+		 * it had been previously dynamically generated, and
+		 * the endpoint is not caching dynamic ACLs.
+		 */
+		mutex_lock(&se_tpg->acl_node_mutex);
+		if (se_nacl->dynamic_node_acl &&
+		    !se_tfo->tpg_check_demo_mode_cache(se_tpg)) {
+			spin_lock_irqsave(&se_nacl->nacl_sess_lock, flags);
+			if (list_empty(&se_nacl->acl_sess_list))
+				se_nacl->dynamic_stop = true;
+			spin_unlock_irqrestore(&se_nacl->nacl_sess_lock, flags);
+
+			if (se_nacl->dynamic_stop)
+				list_del(&se_nacl->acl_list);
+		}
+		mutex_unlock(&se_tpg->acl_node_mutex);
+
+		if (se_nacl->dynamic_stop)
+			target_put_nacl(se_nacl);
+
 		target_put_nacl(se_nacl);
 	}
 	if (se_sess->sess_cmd_map) {
@@ -518,16 +557,12 @@ EXPORT_SYMBOL(transport_free_session);
 void transport_deregister_session(struct se_session *se_sess)
 {
 	struct se_portal_group *se_tpg = se_sess->se_tpg;
-	const struct target_core_fabric_ops *se_tfo;
-	struct se_node_acl *se_nacl;
 	unsigned long flags;
-	bool drop_nacl = false;
 
 	if (!se_tpg) {
 		transport_free_session(se_sess);
 		return;
 	}
-	se_tfo = se_tpg->se_tpg_tfo;
 
 	spin_lock_irqsave(&se_tpg->session_lock, flags);
 	list_del(&se_sess->sess_list);
@@ -535,33 +570,15 @@ void transport_deregister_session(struct
 	se_sess->fabric_sess_ptr = NULL;
 	spin_unlock_irqrestore(&se_tpg->session_lock, flags);
 
-	/*
-	 * Determine if we need to do extra work for this initiator node's
-	 * struct se_node_acl if it had been previously dynamically generated.
-	 */
-	se_nacl = se_sess->se_node_acl;
-
-	mutex_lock(&se_tpg->acl_node_mutex);
-	if (se_nacl && se_nacl->dynamic_node_acl) {
-		if (!se_tfo->tpg_check_demo_mode_cache(se_tpg)) {
-			list_del(&se_nacl->acl_list);
-			drop_nacl = true;
-		}
-	}
-	mutex_unlock(&se_tpg->acl_node_mutex);
-
-	if (drop_nacl) {
-		core_tpg_wait_for_nacl_pr_ref(se_nacl);
-		core_free_device_list_for_node(se_nacl, se_tpg);
-		se_sess->se_node_acl = NULL;
-		kfree(se_nacl);
-	}
 	pr_debug("TARGET_CORE[%s]: Deregistered fabric_sess\n",
 		se_tpg->se_tpg_tfo->get_fabric_name());
 	/*
 	 * If last kref is dropping now for an explicit NodeACL, awake sleeping
 	 * ->acl_free_comp caller to wakeup configfs se_node_acl->acl_group
 	 * removal context from within transport_free_session() code.
+	 *
+	 * For dynamic ACL, target_put_nacl() uses target_complete_nacl()
+	 * to release all remaining generate_node_acl=1 created ACL resources.
 	 */
 
 	transport_free_session(se_sess);
@@ -3110,7 +3127,6 @@ static void target_tmr_work(struct work_
 		spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 		goto check_stop;
 	}
-	cmd->t_state = TRANSPORT_ISTATE_PROCESSING;
 	spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 
 	cmd->se_tfo->queue_tm_rsp(cmd);
@@ -3123,11 +3139,25 @@ int transport_generic_handle_tmr(
 	struct se_cmd *cmd)
 {
 	unsigned long flags;
+	bool aborted = false;
 
 	spin_lock_irqsave(&cmd->t_state_lock, flags);
-	cmd->transport_state |= CMD_T_ACTIVE;
+	if (cmd->transport_state & CMD_T_ABORTED) {
+		aborted = true;
+	} else {
+		cmd->t_state = TRANSPORT_ISTATE_PROCESSING;
+		cmd->transport_state |= CMD_T_ACTIVE;
+	}
 	spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 
+	if (aborted) {
+		pr_warn_ratelimited("handle_tmr caught CMD_T_ABORTED TMR %d"
+			"ref_tag: %llu tag: %llu\n", cmd->se_tmr_req->function,
+			cmd->se_tmr_req->ref_task_tag, cmd->tag);
+		transport_cmd_check_stop_to_fabric(cmd);
+		return 0;
+	}
+
 	INIT_WORK(&cmd->work, target_tmr_work);
 	queue_work(cmd->se_dev->tmr_wq, &cmd->work);
 	return 0;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/target/target_core_xcopy.c linux-libre-4.10-rc8-gnu/drivers/target/target_core_xcopy.c
--- linux-libre-4.10-rc7-gnu/drivers/target/target_core_xcopy.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/target/target_core_xcopy.c	2017-02-12 16:03:20.000000000 -0500
@@ -864,7 +864,7 @@ out:
 			" CHECK_CONDITION -> sending response\n", rc);
 		ec_cmd->scsi_status = SAM_STAT_CHECK_CONDITION;
 	}
-	target_complete_cmd(ec_cmd, SAM_STAT_CHECK_CONDITION);
+	target_complete_cmd(ec_cmd, ec_cmd->scsi_status);
 }
 
 sense_reason_t target_do_xcopy(struct se_cmd *se_cmd)
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/drivers/vfio/vfio_iommu_spapr_tce.c linux-libre-4.10-rc8-gnu/drivers/vfio/vfio_iommu_spapr_tce.c
--- linux-libre-4.10-rc7-gnu/drivers/vfio/vfio_iommu_spapr_tce.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/drivers/vfio/vfio_iommu_spapr_tce.c	2017-02-12 16:03:20.000000000 -0500
@@ -1245,6 +1245,8 @@ static void tce_iommu_release_ownership_
 static long tce_iommu_take_ownership_ddw(struct tce_container *container,
 		struct iommu_table_group *table_group)
 {
+	long i, ret = 0;
+
 	if (!table_group->ops->create_table || !table_group->ops->set_window ||
 			!table_group->ops->release_ownership) {
 		WARN_ON_ONCE(1);
@@ -1253,7 +1255,27 @@ static long tce_iommu_take_ownership_ddw
 
 	table_group->ops->take_ownership(table_group);
 
+	/* Set all windows to the new group */
+	for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) {
+		struct iommu_table *tbl = container->tables[i];
+
+		if (!tbl)
+			continue;
+
+		ret = table_group->ops->set_window(table_group, i, tbl);
+		if (ret)
+			goto release_exit;
+	}
+
 	return 0;
+
+release_exit:
+	for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i)
+		table_group->ops->unset_window(table_group, i);
+
+	table_group->ops->release_ownership(table_group);
+
+	return ret;
 }
 
 static int tce_iommu_attach_group(void *iommu_data,
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/fs/btrfs/compression.c linux-libre-4.10-rc8-gnu/fs/btrfs/compression.c
--- linux-libre-4.10-rc7-gnu/fs/btrfs/compression.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/fs/btrfs/compression.c	2017-02-12 16:03:20.000000000 -0500
@@ -1024,6 +1024,7 @@ int btrfs_decompress_buf2page(char *buf,
 	unsigned long buf_offset;
 	unsigned long current_buf_start;
 	unsigned long start_byte;
+	unsigned long prev_start_byte;
 	unsigned long working_bytes = total_out - buf_start;
 	unsigned long bytes;
 	char *kaddr;
@@ -1071,26 +1072,34 @@ int btrfs_decompress_buf2page(char *buf,
 		if (!bio->bi_iter.bi_size)
 			return 0;
 		bvec = bio_iter_iovec(bio, bio->bi_iter);
-
+		prev_start_byte = start_byte;
 		start_byte = page_offset(bvec.bv_page) - disk_start;
 
 		/*
-		 * make sure our new page is covered by this
-		 * working buffer
+		 * We need to make sure we're only adjusting
+		 * our offset into compression working buffer when
+		 * we're switching pages.  Otherwise we can incorrectly
+		 * keep copying when we were actually done.
 		 */
-		if (total_out <= start_byte)
-			return 1;
+		if (start_byte != prev_start_byte) {
+			/*
+			 * make sure our new page is covered by this
+			 * working buffer
+			 */
+			if (total_out <= start_byte)
+				return 1;
 
-		/*
-		 * the next page in the biovec might not be adjacent
-		 * to the last page, but it might still be found
-		 * inside this working buffer. bump our offset pointer
-		 */
-		if (total_out > start_byte &&
-		    current_buf_start < start_byte) {
-			buf_offset = start_byte - buf_start;
-			working_bytes = total_out - start_byte;
-			current_buf_start = buf_start + buf_offset;
+			/*
+			 * the next page in the biovec might not be adjacent
+			 * to the last page, but it might still be found
+			 * inside this working buffer. bump our offset pointer
+			 */
+			if (total_out > start_byte &&
+			    current_buf_start < start_byte) {
+				buf_offset = start_byte - buf_start;
+				working_bytes = total_out - start_byte;
+				current_buf_start = buf_start + buf_offset;
+			}
 		}
 	}
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/fs/btrfs/ioctl.c linux-libre-4.10-rc8-gnu/fs/btrfs/ioctl.c
--- linux-libre-4.10-rc7-gnu/fs/btrfs/ioctl.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/fs/btrfs/ioctl.c	2017-02-12 16:03:20.000000000 -0500
@@ -5653,6 +5653,10 @@ long btrfs_ioctl(struct file *file, unsi
 #ifdef CONFIG_COMPAT
 long btrfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
+	/*
+	 * These all access 32-bit values anyway so no further
+	 * handling is necessary.
+	 */
 	switch (cmd) {
 	case FS_IOC32_GETFLAGS:
 		cmd = FS_IOC_GETFLAGS;
@@ -5663,8 +5667,6 @@ long btrfs_compat_ioctl(struct file *fil
 	case FS_IOC32_GETVERSION:
 		cmd = FS_IOC_GETVERSION;
 		break;
-	default:
-		return -ENOIOCTLCMD;
 	}
 
 	return btrfs_ioctl(file, cmd, (unsigned long) compat_ptr(arg));
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/fs/nfsd/vfs.c linux-libre-4.10-rc8-gnu/fs/nfsd/vfs.c
--- linux-libre-4.10-rc7-gnu/fs/nfsd/vfs.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/fs/nfsd/vfs.c	2017-02-12 16:03:20.000000000 -0500
@@ -332,6 +332,37 @@ nfsd_sanitize_attrs(struct inode *inode,
 	}
 }
 
+static __be32
+nfsd_get_write_access(struct svc_rqst *rqstp, struct svc_fh *fhp,
+		struct iattr *iap)
+{
+	struct inode *inode = d_inode(fhp->fh_dentry);
+	int host_err;
+
+	if (iap->ia_size < inode->i_size) {
+		__be32 err;
+
+		err = nfsd_permission(rqstp, fhp->fh_export, fhp->fh_dentry,
+				NFSD_MAY_TRUNC | NFSD_MAY_OWNER_OVERRIDE);
+		if (err)
+			return err;
+	}
+
+	host_err = get_write_access(inode);
+	if (host_err)
+		goto out_nfserrno;
+
+	host_err = locks_verify_truncate(inode, NULL, iap->ia_size);
+	if (host_err)
+		goto out_put_write_access;
+	return 0;
+
+out_put_write_access:
+	put_write_access(inode);
+out_nfserrno:
+	return nfserrno(host_err);
+}
+
 /*
  * Set various file attributes.  After this call fhp needs an fh_put.
  */
@@ -346,6 +377,7 @@ nfsd_setattr(struct svc_rqst *rqstp, str
 	__be32		err;
 	int		host_err;
 	bool		get_write_count;
+	int		size_change = 0;
 
 	if (iap->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_SIZE))
 		accmode |= NFSD_MAY_WRITE|NFSD_MAY_OWNER_OVERRIDE;
@@ -358,11 +390,11 @@ nfsd_setattr(struct svc_rqst *rqstp, str
 	/* Get inode */
 	err = fh_verify(rqstp, fhp, ftype, accmode);
 	if (err)
-		return err;
+		goto out;
 	if (get_write_count) {
 		host_err = fh_want_write(fhp);
 		if (host_err)
-			goto out_host_err;
+			return nfserrno(host_err);
 	}
 
 	dentry = fhp->fh_dentry;
@@ -373,59 +405,50 @@ nfsd_setattr(struct svc_rqst *rqstp, str
 		iap->ia_valid &= ~ATTR_MODE;
 
 	if (!iap->ia_valid)
-		return 0;
+		goto out;
 
 	nfsd_sanitize_attrs(inode, iap);
 
-	if (check_guard && guardtime != inode->i_ctime.tv_sec)
-		return nfserr_notsync;
-
 	/*
 	 * The size case is special, it changes the file in addition to the
-	 * attributes, and file systems don't expect it to be mixed with
-	 * "random" attribute changes.  We thus split out the size change
-	 * into a separate call for vfs_truncate, and do the rest as a
-	 * a separate setattr call.
+	 * attributes.
 	 */
 	if (iap->ia_valid & ATTR_SIZE) {
-		struct path path = {
-			.mnt	= fhp->fh_export->ex_path.mnt,
-			.dentry	= dentry,
-		};
-		bool implicit_mtime = false;
+		err = nfsd_get_write_access(rqstp, fhp, iap);
+		if (err)
+			goto out;
+		size_change = 1;
 
 		/*
-		 * vfs_truncate implicity updates the mtime IFF the file size
-		 * actually changes.  Avoid the additional seattr call below if
-		 * the only other attribute that the client sends is the mtime.
+		 * RFC5661, Section 18.30.4:
+		 *   Changing the size of a file with SETATTR indirectly
+		 *   changes the time_modify and change attributes.
+		 *
+		 * (and similar for the older RFCs)
 		 */
-		if (iap->ia_size != i_size_read(inode) &&
-		    ((iap->ia_valid & ~(ATTR_SIZE | ATTR_MTIME)) == 0))
-			implicit_mtime = true;
-
-		host_err = vfs_truncate(&path, iap->ia_size);
-		if (host_err)
-			goto out_host_err;
-
-		iap->ia_valid &= ~ATTR_SIZE;
-		if (implicit_mtime)
-			iap->ia_valid &= ~ATTR_MTIME;
-		if (!iap->ia_valid)
-			goto done;
+		if (iap->ia_size != i_size_read(inode))
+			iap->ia_valid |= ATTR_MTIME;
 	}
 
 	iap->ia_valid |= ATTR_CTIME;
 
+	if (check_guard && guardtime != inode->i_ctime.tv_sec) {
+		err = nfserr_notsync;
+		goto out_put_write_access;
+	}
+
 	fh_lock(fhp);
 	host_err = notify_change(dentry, iap, NULL);
 	fh_unlock(fhp);
-	if (host_err)
-		goto out_host_err;
+	err = nfserrno(host_err);
 
-done:
-	host_err = commit_metadata(fhp);
-out_host_err:
-	return nfserrno(host_err);
+out_put_write_access:
+	if (size_change)
+		put_write_access(inode);
+	if (!err)
+		err = nfserrno(commit_metadata(fhp));
+out:
+	return err;
 }
 
 #if defined(CONFIG_NFSD_V4)
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/fs/proc/page.c linux-libre-4.10-rc8-gnu/fs/proc/page.c
--- linux-libre-4.10-rc7-gnu/fs/proc/page.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/fs/proc/page.c	2017-02-12 16:03:20.000000000 -0500
@@ -173,7 +173,8 @@ u64 stable_page_flags(struct page *page)
 	u |= kpf_copy_bit(k, KPF_ACTIVE,	PG_active);
 	u |= kpf_copy_bit(k, KPF_RECLAIM,	PG_reclaim);
 
-	u |= kpf_copy_bit(k, KPF_SWAPCACHE,	PG_swapcache);
+	if (PageSwapCache(page))
+		u |= 1 << KPF_SWAPCACHE;
 	u |= kpf_copy_bit(k, KPF_SWAPBACKED,	PG_swapbacked);
 
 	u |= kpf_copy_bit(k, KPF_UNEVICTABLE,	PG_unevictable);
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/fs/pstore/ram.c linux-libre-4.10-rc8-gnu/fs/pstore/ram.c
--- linux-libre-4.10-rc7-gnu/fs/pstore/ram.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/fs/pstore/ram.c	2017-02-12 16:03:20.000000000 -0500
@@ -280,7 +280,7 @@ static ssize_t ramoops_pstore_read(u64 *
 					   1, id, type, PSTORE_TYPE_PMSG, 0);
 
 	/* ftrace is last since it may want to dynamically allocate memory. */
-	if (!prz_ok(prz)) {
+	if (!prz_ok(prz) && cxt->fprzs) {
 		if (!(cxt->flags & RAMOOPS_FLAG_FTRACE_PER_CPU)) {
 			prz = ramoops_get_next_prz(cxt->fprzs,
 					&cxt->ftrace_read_cnt, 1, id, type,
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/include/linux/buffer_head.h linux-libre-4.10-rc8-gnu/include/linux/buffer_head.h
--- linux-libre-4.10-rc7-gnu/include/linux/buffer_head.h	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/include/linux/buffer_head.h	2017-02-12 16:03:20.000000000 -0500
@@ -243,12 +243,10 @@ static inline int block_page_mkwrite_ret
 {
 	if (err == 0)
 		return VM_FAULT_LOCKED;
-	if (err == -EFAULT)
+	if (err == -EFAULT || err == -EAGAIN)
 		return VM_FAULT_NOPAGE;
 	if (err == -ENOMEM)
 		return VM_FAULT_OOM;
-	if (err == -EAGAIN)
-		return VM_FAULT_RETRY;
 	/* -ENOSPC, -EDQUOT, -EIO ... */
 	return VM_FAULT_SIGBUS;
 }
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/include/linux/cpumask.h linux-libre-4.10-rc8-gnu/include/linux/cpumask.h
--- linux-libre-4.10-rc7-gnu/include/linux/cpumask.h	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/include/linux/cpumask.h	2017-02-12 16:03:20.000000000 -0500
@@ -560,7 +560,7 @@ static inline void cpumask_copy(struct c
 static inline int cpumask_parse_user(const char __user *buf, int len,
 				     struct cpumask *dstp)
 {
-	return bitmap_parse_user(buf, len, cpumask_bits(dstp), nr_cpu_ids);
+	return bitmap_parse_user(buf, len, cpumask_bits(dstp), nr_cpumask_bits);
 }
 
 /**
@@ -575,7 +575,7 @@ static inline int cpumask_parselist_user
 				     struct cpumask *dstp)
 {
 	return bitmap_parselist_user(buf, len, cpumask_bits(dstp),
-				     nr_cpu_ids);
+				     nr_cpumask_bits);
 }
 
 /**
@@ -590,7 +590,7 @@ static inline int cpumask_parse(const ch
 	char *nl = strchr(buf, '\n');
 	unsigned int len = nl ? (unsigned int)(nl - buf) : strlen(buf);
 
-	return bitmap_parse(buf, len, cpumask_bits(dstp), nr_cpu_ids);
+	return bitmap_parse(buf, len, cpumask_bits(dstp), nr_cpumask_bits);
 }
 
 /**
@@ -602,7 +602,7 @@ static inline int cpumask_parse(const ch
  */
 static inline int cpulist_parse(const char *buf, struct cpumask *dstp)
 {
-	return bitmap_parselist(buf, cpumask_bits(dstp), nr_cpu_ids);
+	return bitmap_parselist(buf, cpumask_bits(dstp), nr_cpumask_bits);
 }
 
 /**
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/include/linux/netdevice.h linux-libre-4.10-rc8-gnu/include/linux/netdevice.h
--- linux-libre-4.10-rc7-gnu/include/linux/netdevice.h	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/include/linux/netdevice.h	2017-02-12 16:03:20.000000000 -0500
@@ -1511,6 +1511,7 @@ enum netdev_priv_flags {
  *	@max_mtu:	Interface Maximum MTU value
  *	@type:		Interface hardware type
  *	@hard_header_len: Maximum hardware header length.
+ *	@min_header_len:  Minimum hardware header length
  *
  *	@needed_headroom: Extra headroom the hardware may need, but not in all
  *			  cases can this be guaranteed
@@ -1728,6 +1729,7 @@ struct net_device {
 	unsigned int		max_mtu;
 	unsigned short		type;
 	unsigned short		hard_header_len;
+	unsigned short		min_header_len;
 
 	unsigned short		needed_headroom;
 	unsigned short		needed_tailroom;
@@ -2694,6 +2696,8 @@ static inline bool dev_validate_header(c
 {
 	if (likely(len >= dev->hard_header_len))
 		return true;
+	if (len < dev->min_header_len)
+		return false;
 
 	if (capable(CAP_SYS_RAWIO)) {
 		memset(ll_header + len, 0, dev->hard_header_len - len);
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/include/net/cipso_ipv4.h linux-libre-4.10-rc8-gnu/include/net/cipso_ipv4.h
--- linux-libre-4.10-rc7-gnu/include/net/cipso_ipv4.h	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/include/net/cipso_ipv4.h	2017-02-12 16:03:20.000000000 -0500
@@ -309,6 +309,10 @@ static inline int cipso_v4_validate(cons
 	}
 
 	for (opt_iter = 6; opt_iter < opt_len;) {
+		if (opt_iter + 1 == opt_len) {
+			err_offset = opt_iter;
+			goto out;
+		}
 		tag_len = opt[opt_iter + 1];
 		if ((tag_len == 0) || (tag_len > (opt_len - opt_iter))) {
 			err_offset = opt_iter + 1;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/include/net/lwtunnel.h linux-libre-4.10-rc8-gnu/include/net/lwtunnel.h
--- linux-libre-4.10-rc7-gnu/include/net/lwtunnel.h	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/include/net/lwtunnel.h	2017-02-12 16:03:20.000000000 -0500
@@ -178,7 +178,10 @@ static inline int lwtunnel_valid_encap_t
 }
 static inline int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len)
 {
-	return -EOPNOTSUPP;
+	/* return 0 since we are not walking attr looking for
+	 * RTA_ENCAP_TYPE attribute on nexthops.
+	 */
+	return 0;
 }
 
 static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/include/net/sock.h linux-libre-4.10-rc8-gnu/include/net/sock.h
--- linux-libre-4.10-rc7-gnu/include/net/sock.h	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/include/net/sock.h	2017-02-12 16:03:20.000000000 -0500
@@ -2006,7 +2006,9 @@ void sk_reset_timer(struct sock *sk, str
 void sk_stop_timer(struct sock *sk, struct timer_list *timer);
 
 int __sk_queue_drop_skb(struct sock *sk, struct sk_buff *skb,
-			unsigned int flags);
+			unsigned int flags,
+			void (*destructor)(struct sock *sk,
+					   struct sk_buff *skb));
 int __sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
 int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/include/target/target_core_base.h linux-libre-4.10-rc8-gnu/include/target/target_core_base.h
--- linux-libre-4.10-rc7-gnu/include/target/target_core_base.h	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/include/target/target_core_base.h	2017-02-12 16:03:20.000000000 -0500
@@ -538,6 +538,7 @@ struct se_node_acl {
 	char			initiatorname[TRANSPORT_IQN_LEN];
 	/* Used to signal demo mode created ACL, disabled by default */
 	bool			dynamic_node_acl;
+	bool			dynamic_stop;
 	u32			queue_depth;
 	u32			acl_index;
 	enum target_prot_type	saved_prot_type;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/include/uapi/linux/seg6.h linux-libre-4.10-rc8-gnu/include/uapi/linux/seg6.h
--- linux-libre-4.10-rc7-gnu/include/uapi/linux/seg6.h	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/include/uapi/linux/seg6.h	2017-02-12 16:03:20.000000000 -0500
@@ -23,14 +23,12 @@ struct ipv6_sr_hdr {
 	__u8	type;
 	__u8	segments_left;
 	__u8	first_segment;
-	__u8	flag_1;
-	__u8	flag_2;
-	__u8	reserved;
+	__u8	flags;
+	__u16	reserved;
 
 	struct in6_addr segments[0];
 };
 
-#define SR6_FLAG1_CLEANUP	(1 << 7)
 #define SR6_FLAG1_PROTECTED	(1 << 6)
 #define SR6_FLAG1_OAM		(1 << 5)
 #define SR6_FLAG1_ALERT		(1 << 4)
@@ -42,8 +40,7 @@ struct ipv6_sr_hdr {
 #define SR6_TLV_PADDING		4
 #define SR6_TLV_HMAC		5
 
-#define sr_has_cleanup(srh) ((srh)->flag_1 & SR6_FLAG1_CLEANUP)
-#define sr_has_hmac(srh) ((srh)->flag_1 & SR6_FLAG1_HMAC)
+#define sr_has_hmac(srh) ((srh)->flags & SR6_FLAG1_HMAC)
 
 struct sr6_tlv {
 	__u8 type;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/include/uapi/rdma/ib_user_verbs.h linux-libre-4.10-rc8-gnu/include/uapi/rdma/ib_user_verbs.h
--- linux-libre-4.10-rc7-gnu/include/uapi/rdma/ib_user_verbs.h	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/include/uapi/rdma/ib_user_verbs.h	2017-02-12 16:03:20.000000000 -0500
@@ -37,7 +37,6 @@
 #define IB_USER_VERBS_H
 
 #include <linux/types.h>
-#include <rdma/ib_verbs.h>
 
 /*
  * Increment this value if any changes that break userspace ABI
@@ -548,11 +547,17 @@ enum {
 };
 
 enum {
-	IB_USER_LEGACY_LAST_QP_ATTR_MASK = IB_QP_DEST_QPN
+	/*
+	 * This value is equal to IB_QP_DEST_QPN.
+	 */
+	IB_USER_LEGACY_LAST_QP_ATTR_MASK = 1ULL << 20,
 };
 
 enum {
-	IB_USER_LAST_QP_ATTR_MASK = IB_QP_RATE_LIMIT
+	/*
+	 * This value is equal to IB_QP_RATE_LIMIT.
+	 */
+	IB_USER_LAST_QP_ATTR_MASK = 1ULL << 25,
 };
 
 struct ib_uverbs_ex_create_qp {
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/kernel/events/core.c linux-libre-4.10-rc8-gnu/kernel/events/core.c
--- linux-libre-4.10-rc7-gnu/kernel/events/core.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/kernel/events/core.c	2017-02-12 16:03:20.000000000 -0500
@@ -3487,14 +3487,15 @@ struct perf_read_data {
 	int ret;
 };
 
-static int find_cpu_to_read(struct perf_event *event, int local_cpu)
+static int __perf_event_read_cpu(struct perf_event *event, int event_cpu)
 {
-	int event_cpu = event->oncpu;
 	u16 local_pkg, event_pkg;
 
 	if (event->group_caps & PERF_EV_CAP_READ_ACTIVE_PKG) {
-		event_pkg =  topology_physical_package_id(event_cpu);
-		local_pkg =  topology_physical_package_id(local_cpu);
+		int local_cpu = smp_processor_id();
+
+		event_pkg = topology_physical_package_id(event_cpu);
+		local_pkg = topology_physical_package_id(local_cpu);
 
 		if (event_pkg == local_pkg)
 			return local_cpu;
@@ -3624,7 +3625,7 @@ u64 perf_event_read_local(struct perf_ev
 
 static int perf_event_read(struct perf_event *event, bool group)
 {
-	int ret = 0, cpu_to_read, local_cpu;
+	int event_cpu, ret = 0;
 
 	/*
 	 * If event is enabled and currently active on a CPU, update the
@@ -3637,21 +3638,25 @@ static int perf_event_read(struct perf_e
 			.ret = 0,
 		};
 
-		local_cpu = get_cpu();
-		cpu_to_read = find_cpu_to_read(event, local_cpu);
-		put_cpu();
+		event_cpu = READ_ONCE(event->oncpu);
+		if ((unsigned)event_cpu >= nr_cpu_ids)
+			return 0;
+
+		preempt_disable();
+		event_cpu = __perf_event_read_cpu(event, event_cpu);
 
 		/*
 		 * Purposely ignore the smp_call_function_single() return
 		 * value.
 		 *
-		 * If event->oncpu isn't a valid CPU it means the event got
+		 * If event_cpu isn't a valid CPU it means the event got
 		 * scheduled out and that will have updated the event count.
 		 *
 		 * Therefore, either way, we'll have an up-to-date event count
 		 * after this.
 		 */
-		(void)smp_call_function_single(cpu_to_read, __perf_event_read, &data, 1);
+		(void)smp_call_function_single(event_cpu, __perf_event_read, &data, 1);
+		preempt_enable();
 		ret = data.ret;
 	} else if (event->state == PERF_EVENT_STATE_INACTIVE) {
 		struct perf_event_context *ctx = event->ctx;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/kernel/stacktrace.c linux-libre-4.10-rc8-gnu/kernel/stacktrace.c
--- linux-libre-4.10-rc7-gnu/kernel/stacktrace.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/kernel/stacktrace.c	2017-02-12 16:03:20.000000000 -0500
@@ -18,10 +18,8 @@ void print_stack_trace(struct stack_trac
 	if (WARN_ON(!trace->entries))
 		return;
 
-	for (i = 0; i < trace->nr_entries; i++) {
-		printk("%*c", 1 + spaces, ' ');
-		print_ip_sym(trace->entries[i]);
-	}
+	for (i = 0; i < trace->nr_entries; i++)
+		printk("%*c%pS\n", 1 + spaces, ' ', (void *)trace->entries[i]);
 }
 EXPORT_SYMBOL_GPL(print_stack_trace);
 
@@ -29,7 +27,6 @@ int snprint_stack_trace(char *buf, size_
 			struct stack_trace *trace, int spaces)
 {
 	int i;
-	unsigned long ip;
 	int generated;
 	int total = 0;
 
@@ -37,9 +34,8 @@ int snprint_stack_trace(char *buf, size_
 		return 0;
 
 	for (i = 0; i < trace->nr_entries; i++) {
-		ip = trace->entries[i];
-		generated = snprintf(buf, size, "%*c[<%p>] %pS\n",
-				1 + spaces, ' ', (void *) ip, (void *) ip);
+		generated = snprintf(buf, size, "%*c%pS\n", 1 + spaces, ' ',
+				     (void *)trace->entries[i]);
 
 		total += generated;
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/kernel/time/tick-sched.c linux-libre-4.10-rc8-gnu/kernel/time/tick-sched.c
--- linux-libre-4.10-rc7-gnu/kernel/time/tick-sched.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/kernel/time/tick-sched.c	2017-02-12 16:03:20.000000000 -0500
@@ -725,6 +725,11 @@ static ktime_t tick_nohz_stop_sched_tick
 		 */
 		if (delta == 0) {
 			tick_nohz_restart(ts, now);
+			/*
+			 * Make sure next tick stop doesn't get fooled by past
+			 * clock deadline
+			 */
+			ts->next_tick = 0;
 			goto out;
 		}
 	}
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/kernel/ucount.c linux-libre-4.10-rc8-gnu/kernel/ucount.c
--- linux-libre-4.10-rc7-gnu/kernel/ucount.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/kernel/ucount.c	2017-02-12 16:03:20.000000000 -0500
@@ -227,11 +227,10 @@ static __init int user_namespace_sysctl_
 	 * properly.
 	 */
 	user_header = register_sysctl("user", empty);
+	kmemleak_ignore(user_header);
 	BUG_ON(!user_header);
 	BUG_ON(!setup_userns_sysctls(&init_user_ns));
 #endif
 	return 0;
 }
 subsys_initcall(user_namespace_sysctl_init);
-
-
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/MAINTAINERS linux-libre-4.10-rc8-gnu/MAINTAINERS
--- linux-libre-4.10-rc7-gnu/MAINTAINERS	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/MAINTAINERS	2017-02-12 16:03:20.000000000 -0500
@@ -1091,7 +1091,7 @@ F:	arch/arm/boot/dts/aspeed-*
 F:	drivers/*/*aspeed*
 
 ARM/ATMEL AT91RM9200, AT91SAM9 AND SAMA5 SOC SUPPORT
-M:	Nicolas Ferre <nicolas.ferre@atmel.com>
+M:	Nicolas Ferre <nicolas.ferre@microchip.com>
 M:	Alexandre Belloni <alexandre.belloni@free-electrons.com>
 M:	Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1773,7 +1773,7 @@ F:	drivers/soc/renesas/
 F:	include/linux/soc/renesas/
 
 ARM/SOCFPGA ARCHITECTURE
-M:	Dinh Nguyen <dinguyen@opensource.altera.com>
+M:	Dinh Nguyen <dinguyen@kernel.org>
 S:	Maintained
 F:	arch/arm/mach-socfpga/
 F:	arch/arm/boot/dts/socfpga*
@@ -1783,7 +1783,7 @@ W:	http://www.rocketboards.org
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux.git
 
 ARM/SOCFPGA CLOCK FRAMEWORK SUPPORT
-M:	Dinh Nguyen <dinguyen@opensource.altera.com>
+M:	Dinh Nguyen <dinguyen@kernel.org>
 S:	Maintained
 F:	drivers/clk/socfpga/
 
@@ -2175,56 +2175,56 @@ F:	include/linux/atm*
 F:	include/uapi/linux/atm*
 
 ATMEL AT91 / AT32 MCI DRIVER
-M:	Ludovic Desroches <ludovic.desroches@atmel.com>
+M:	Ludovic Desroches <ludovic.desroches@microchip.com>
 S:	Maintained
 F:	drivers/mmc/host/atmel-mci.c
 
 ATMEL AT91 SAMA5D2-Compatible Shutdown Controller
-M:	Nicolas Ferre <nicolas.ferre@atmel.com>
+M:	Nicolas Ferre <nicolas.ferre@microchip.com>
 S:	Supported
 F:	drivers/power/reset/at91-sama5d2_shdwc.c
 
 ATMEL SAMA5D2 ADC DRIVER
-M:	Ludovic Desroches <ludovic.desroches@atmel.com>
+M:	Ludovic Desroches <ludovic.desroches@microchip.com>
 L:	linux-iio@vger.kernel.org
 S:	Supported
 F:	drivers/iio/adc/at91-sama5d2_adc.c
 
 ATMEL Audio ALSA driver
-M:	Nicolas Ferre <nicolas.ferre@atmel.com>
+M:	Nicolas Ferre <nicolas.ferre@microchip.com>
 L:	alsa-devel@alsa-project.org (moderated for non-subscribers)
 S:	Supported
 F:	sound/soc/atmel
 
 ATMEL XDMA DRIVER
-M:	Ludovic Desroches <ludovic.desroches@atmel.com>
+M:	Ludovic Desroches <ludovic.desroches@microchip.com>
 L:	linux-arm-kernel@lists.infradead.org
 L:	dmaengine@vger.kernel.org
 S:	Supported
 F:	drivers/dma/at_xdmac.c
 
 ATMEL I2C DRIVER
-M:	Ludovic Desroches <ludovic.desroches@atmel.com>
+M:	Ludovic Desroches <ludovic.desroches@microchip.com>
 L:	linux-i2c@vger.kernel.org
 S:	Supported
 F:	drivers/i2c/busses/i2c-at91.c
 
 ATMEL ISI DRIVER
-M:	Ludovic Desroches <ludovic.desroches@atmel.com>
+M:	Ludovic Desroches <ludovic.desroches@microchip.com>
 L:	linux-media@vger.kernel.org
 S:	Supported
 F:	drivers/media/platform/soc_camera/atmel-isi.c
 F:	include/media/atmel-isi.h
 
 ATMEL LCDFB DRIVER
-M:	Nicolas Ferre <nicolas.ferre@atmel.com>
+M:	Nicolas Ferre <nicolas.ferre@microchip.com>
 L:	linux-fbdev@vger.kernel.org
 S:	Maintained
 F:	drivers/video/fbdev/atmel_lcdfb.c
 F:	include/video/atmel_lcdc.h
 
 ATMEL MACB ETHERNET DRIVER
-M:	Nicolas Ferre <nicolas.ferre@atmel.com>
+M:	Nicolas Ferre <nicolas.ferre@microchip.com>
 S:	Supported
 F:	drivers/net/ethernet/cadence/
 
@@ -2236,32 +2236,32 @@ S:	Supported
 F:	drivers/mtd/nand/atmel_nand*
 
 ATMEL SDMMC DRIVER
-M:	Ludovic Desroches <ludovic.desroches@atmel.com>
+M:	Ludovic Desroches <ludovic.desroches@microchip.com>
 L:	linux-mmc@vger.kernel.org
 S:	Supported
 F:	drivers/mmc/host/sdhci-of-at91.c
 
 ATMEL SPI DRIVER
-M:	Nicolas Ferre <nicolas.ferre@atmel.com>
+M:	Nicolas Ferre <nicolas.ferre@microchip.com>
 S:	Supported
 F:	drivers/spi/spi-atmel.*
 
 ATMEL SSC DRIVER
-M:	Nicolas Ferre <nicolas.ferre@atmel.com>
+M:	Nicolas Ferre <nicolas.ferre@microchip.com>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:	Supported
 F:	drivers/misc/atmel-ssc.c
 F:	include/linux/atmel-ssc.h
 
 ATMEL Timer Counter (TC) AND CLOCKSOURCE DRIVERS
-M:	Nicolas Ferre <nicolas.ferre@atmel.com>
+M:	Nicolas Ferre <nicolas.ferre@microchip.com>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:	Supported
 F:	drivers/misc/atmel_tclib.c
 F:	drivers/clocksource/tcb_clksrc.c
 
 ATMEL USBA UDC DRIVER
-M:	Nicolas Ferre <nicolas.ferre@atmel.com>
+M:	Nicolas Ferre <nicolas.ferre@microchip.com>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:	Supported
 F:	drivers/usb/gadget/udc/atmel_usba_udc.*
@@ -9736,7 +9736,7 @@ S:	Maintained
 F:	drivers/pinctrl/pinctrl-at91.*
 
 PIN CONTROLLER - ATMEL AT91 PIO4
-M:	Ludovic Desroches <ludovic.desroches@atmel.com>
+M:	Ludovic Desroches <ludovic.desroches@microchip.com>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 L:	linux-gpio@vger.kernel.org
 S:	Supported
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/Makefile linux-libre-4.10-rc8-gnu/Makefile
--- linux-libre-4.10-rc7-gnu/Makefile	2017-02-06 10:45:56.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/Makefile	2017-02-12 17:21:10.000000000 -0500
@@ -1,7 +1,7 @@
 VERSION = 4
 PATCHLEVEL = 10
 SUBLEVEL = 0
-EXTRAVERSION = -rc7-gnu
+EXTRAVERSION = -rc8-gnu
 NAME = Fearless Coyote
 
 # *DOCUMENTATION*
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/mm/slub.c linux-libre-4.10-rc8-gnu/mm/slub.c
--- linux-libre-4.10-rc7-gnu/mm/slub.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/mm/slub.c	2017-02-12 16:03:20.000000000 -0500
@@ -1422,6 +1422,10 @@ static int init_cache_random_seq(struct
 	int err;
 	unsigned long i, count = oo_objects(s->oo);
 
+	/* Bailout if already initialised */
+	if (s->random_seq)
+		return 0;
+
 	err = cache_random_seq_create(s, count, GFP_KERNEL);
 	if (err) {
 		pr_err("SLUB: Unable to initialize free list for %s\n",
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/net/core/datagram.c linux-libre-4.10-rc8-gnu/net/core/datagram.c
--- linux-libre-4.10-rc7-gnu/net/core/datagram.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/net/core/datagram.c	2017-02-12 16:03:20.000000000 -0500
@@ -332,7 +332,9 @@ void __skb_free_datagram_locked(struct s
 EXPORT_SYMBOL(__skb_free_datagram_locked);
 
 int __sk_queue_drop_skb(struct sock *sk, struct sk_buff *skb,
-			unsigned int flags)
+			unsigned int flags,
+			void (*destructor)(struct sock *sk,
+					   struct sk_buff *skb))
 {
 	int err = 0;
 
@@ -342,6 +344,8 @@ int __sk_queue_drop_skb(struct sock *sk,
 		if (skb == skb_peek(&sk->sk_receive_queue)) {
 			__skb_unlink(skb, &sk->sk_receive_queue);
 			atomic_dec(&skb->users);
+			if (destructor)
+				destructor(sk, skb);
 			err = 0;
 		}
 		spin_unlock_bh(&sk->sk_receive_queue.lock);
@@ -375,7 +379,7 @@ EXPORT_SYMBOL(__sk_queue_drop_skb);
 
 int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags)
 {
-	int err = __sk_queue_drop_skb(sk, skb, flags);
+	int err = __sk_queue_drop_skb(sk, skb, flags, NULL);
 
 	kfree_skb(skb);
 	sk_mem_reclaim_partial(sk);
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/net/core/dev.c linux-libre-4.10-rc8-gnu/net/core/dev.c
--- linux-libre-4.10-rc7-gnu/net/core/dev.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/net/core/dev.c	2017-02-12 16:03:20.000000000 -0500
@@ -1695,24 +1695,19 @@ EXPORT_SYMBOL_GPL(net_dec_egress_queue);
 
 static struct static_key netstamp_needed __read_mostly;
 #ifdef HAVE_JUMP_LABEL
-/* We are not allowed to call static_key_slow_dec() from irq context
- * If net_disable_timestamp() is called from irq context, defer the
- * static_key_slow_dec() calls.
- */
 static atomic_t netstamp_needed_deferred;
-#endif
-
-void net_enable_timestamp(void)
+static void netstamp_clear(struct work_struct *work)
 {
-#ifdef HAVE_JUMP_LABEL
 	int deferred = atomic_xchg(&netstamp_needed_deferred, 0);
 
-	if (deferred) {
-		while (--deferred)
-			static_key_slow_dec(&netstamp_needed);
-		return;
-	}
+	while (deferred--)
+		static_key_slow_dec(&netstamp_needed);
+}
+static DECLARE_WORK(netstamp_work, netstamp_clear);
 #endif
+
+void net_enable_timestamp(void)
+{
 	static_key_slow_inc(&netstamp_needed);
 }
 EXPORT_SYMBOL(net_enable_timestamp);
@@ -1720,12 +1715,12 @@ EXPORT_SYMBOL(net_enable_timestamp);
 void net_disable_timestamp(void)
 {
 #ifdef HAVE_JUMP_LABEL
-	if (in_interrupt()) {
-		atomic_inc(&netstamp_needed_deferred);
-		return;
-	}
-#endif
+	/* net_disable_timestamp() can be called from non process context */
+	atomic_inc(&netstamp_needed_deferred);
+	schedule_work(&netstamp_work);
+#else
 	static_key_slow_dec(&netstamp_needed);
+#endif
 }
 EXPORT_SYMBOL(net_disable_timestamp);
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/net/core/ethtool.c linux-libre-4.10-rc8-gnu/net/core/ethtool.c
--- linux-libre-4.10-rc7-gnu/net/core/ethtool.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/net/core/ethtool.c	2017-02-12 16:03:20.000000000 -0500
@@ -1405,9 +1405,12 @@ static int ethtool_get_regs(struct net_d
 	if (regs.len > reglen)
 		regs.len = reglen;
 
-	regbuf = vzalloc(reglen);
-	if (reglen && !regbuf)
-		return -ENOMEM;
+	regbuf = NULL;
+	if (reglen) {
+		regbuf = vzalloc(reglen);
+		if (!regbuf)
+			return -ENOMEM;
+	}
 
 	ops->get_regs(dev, &regs, regbuf);
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/net/dsa/dsa2.c linux-libre-4.10-rc8-gnu/net/dsa/dsa2.c
--- linux-libre-4.10-rc7-gnu/net/dsa/dsa2.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/net/dsa/dsa2.c	2017-02-12 16:03:20.000000000 -0500
@@ -273,6 +273,7 @@ static int dsa_user_port_apply(struct de
 	if (err) {
 		dev_warn(ds->dev, "Failed to create slave %d: %d\n",
 			 index, err);
+		ds->ports[index].netdev = NULL;
 		return err;
 	}
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/net/ethernet/eth.c linux-libre-4.10-rc8-gnu/net/ethernet/eth.c
--- linux-libre-4.10-rc7-gnu/net/ethernet/eth.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/net/ethernet/eth.c	2017-02-12 16:03:20.000000000 -0500
@@ -356,6 +356,7 @@ void ether_setup(struct net_device *dev)
 	dev->header_ops		= &eth_header_ops;
 	dev->type		= ARPHRD_ETHER;
 	dev->hard_header_len 	= ETH_HLEN;
+	dev->min_header_len	= ETH_HLEN;
 	dev->mtu		= ETH_DATA_LEN;
 	dev->min_mtu		= ETH_MIN_MTU;
 	dev->max_mtu		= ETH_DATA_LEN;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/net/ipv4/cipso_ipv4.c linux-libre-4.10-rc8-gnu/net/ipv4/cipso_ipv4.c
--- linux-libre-4.10-rc7-gnu/net/ipv4/cipso_ipv4.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/net/ipv4/cipso_ipv4.c	2017-02-12 16:03:20.000000000 -0500
@@ -1587,6 +1587,10 @@ int cipso_v4_validate(const struct sk_bu
 				goto validate_return_locked;
 			}
 
+		if (opt_iter + 1 == opt_len) {
+			err_offset = opt_iter;
+			goto validate_return_locked;
+		}
 		tag_len = tag[1];
 		if (tag_len > (opt_len - opt_iter)) {
 			err_offset = opt_iter + 1;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/net/ipv4/igmp.c linux-libre-4.10-rc8-gnu/net/ipv4/igmp.c
--- linux-libre-4.10-rc7-gnu/net/ipv4/igmp.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/net/ipv4/igmp.c	2017-02-12 16:03:20.000000000 -0500
@@ -1172,6 +1172,7 @@ static void igmpv3_del_delrec(struct in_
 				psf->sf_crcount = im->crcount;
 		}
 		in_dev_put(pmc->interface);
+		kfree(pmc);
 	}
 	spin_unlock_bh(&im->lock);
 }
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/net/ipv4/ip_sockglue.c linux-libre-4.10-rc8-gnu/net/ipv4/ip_sockglue.c
--- linux-libre-4.10-rc7-gnu/net/ipv4/ip_sockglue.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/net/ipv4/ip_sockglue.c	2017-02-12 16:03:20.000000000 -0500
@@ -1238,7 +1238,14 @@ void ipv4_pktinfo_prepare(const struct s
 		pktinfo->ipi_ifindex = 0;
 		pktinfo->ipi_spec_dst.s_addr = 0;
 	}
-	skb_dst_drop(skb);
+	/* We need to keep the dst for __ip_options_echo()
+	 * We could restrict the test to opt.ts_needtime || opt.srr,
+	 * but the following is good enough as IP options are not often used.
+	 */
+	if (unlikely(IPCB(skb)->opt.optlen))
+		skb_dst_force(skb);
+	else
+		skb_dst_drop(skb);
 }
 
 int ip_setsockopt(struct sock *sk, int level,
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/net/ipv4/ping.c linux-libre-4.10-rc8-gnu/net/ipv4/ping.c
--- linux-libre-4.10-rc7-gnu/net/ipv4/ping.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/net/ipv4/ping.c	2017-02-12 16:03:20.000000000 -0500
@@ -642,6 +642,8 @@ static int ping_v4_push_pending_frames(s
 {
 	struct sk_buff *skb = skb_peek(&sk->sk_write_queue);
 
+	if (!skb)
+		return 0;
 	pfh->wcheck = csum_partial((char *)&pfh->icmph,
 		sizeof(struct icmphdr), pfh->wcheck);
 	pfh->icmph.checksum = csum_fold(pfh->wcheck);
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/net/ipv4/tcp.c linux-libre-4.10-rc8-gnu/net/ipv4/tcp.c
--- linux-libre-4.10-rc7-gnu/net/ipv4/tcp.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/net/ipv4/tcp.c	2017-02-12 16:03:20.000000000 -0500
@@ -770,6 +770,12 @@ ssize_t tcp_splice_read(struct socket *s
 				ret = -EAGAIN;
 				break;
 			}
+			/* if __tcp_splice_read() got nothing while we have
+			 * an skb in receive queue, we do not want to loop.
+			 * This might happen with URG data.
+			 */
+			if (!skb_queue_empty(&sk->sk_receive_queue))
+				break;
 			sk_wait_data(sk, &timeo, NULL);
 			if (signal_pending(current)) {
 				ret = sock_intr_errno(timeo);
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/net/ipv4/udp.c linux-libre-4.10-rc8-gnu/net/ipv4/udp.c
--- linux-libre-4.10-rc7-gnu/net/ipv4/udp.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/net/ipv4/udp.c	2017-02-12 16:03:20.000000000 -0500
@@ -1501,7 +1501,7 @@ try_again:
 	return err;
 
 csum_copy_err:
-	if (!__sk_queue_drop_skb(sk, skb, flags)) {
+	if (!__sk_queue_drop_skb(sk, skb, flags, udp_skb_destructor)) {
 		UDP_INC_STATS(sock_net(sk), UDP_MIB_CSUMERRORS, is_udplite);
 		UDP_INC_STATS(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
 	}
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/net/ipv6/addrconf.c linux-libre-4.10-rc8-gnu/net/ipv6/addrconf.c
--- linux-libre-4.10-rc7-gnu/net/ipv6/addrconf.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/net/ipv6/addrconf.c	2017-02-12 16:03:20.000000000 -0500
@@ -3386,9 +3386,15 @@ static int addrconf_notify(struct notifi
 			}
 
 			if (idev) {
-				if (idev->if_flags & IF_READY)
-					/* device is already configured. */
+				if (idev->if_flags & IF_READY) {
+					/* device is already configured -
+					 * but resend MLD reports, we might
+					 * have roamed and need to update
+					 * multicast snooping switches
+					 */
+					ipv6_mc_up(idev);
 					break;
+				}
 				idev->if_flags |= IF_READY;
 			}
 
@@ -4009,6 +4015,12 @@ static void addrconf_dad_completed(struc
 
 	if (bump_id)
 		rt_genid_bump_ipv6(dev_net(dev));
+
+	/* Make sure that a new temporary address will be created
+	 * before this temporary address becomes deprecated.
+	 */
+	if (ifp->flags & IFA_F_TEMPORARY)
+		addrconf_verify_rtnl();
 }
 
 static void addrconf_dad_run(struct inet6_dev *idev)
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/net/ipv6/exthdrs.c linux-libre-4.10-rc8-gnu/net/ipv6/exthdrs.c
--- linux-libre-4.10-rc7-gnu/net/ipv6/exthdrs.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/net/ipv6/exthdrs.c	2017-02-12 16:03:20.000000000 -0500
@@ -327,7 +327,6 @@ static int ipv6_srh_rcv(struct sk_buff *
 	struct ipv6_sr_hdr *hdr;
 	struct inet6_dev *idev;
 	struct in6_addr *addr;
-	bool cleanup = false;
 	int accept_seg6;
 
 	hdr = (struct ipv6_sr_hdr *)skb_transport_header(skb);
@@ -351,11 +350,7 @@ static int ipv6_srh_rcv(struct sk_buff *
 #endif
 
 looped_back:
-	if (hdr->segments_left > 0) {
-		if (hdr->nexthdr != NEXTHDR_IPV6 && hdr->segments_left == 1 &&
-		    sr_has_cleanup(hdr))
-			cleanup = true;
-	} else {
+	if (hdr->segments_left == 0) {
 		if (hdr->nexthdr == NEXTHDR_IPV6) {
 			int offset = (hdr->hdrlen + 1) << 3;
 
@@ -418,21 +413,6 @@ looped_back:
 
 	ipv6_hdr(skb)->daddr = *addr;
 
-	if (cleanup) {
-		int srhlen = (hdr->hdrlen + 1) << 3;
-		int nh = hdr->nexthdr;
-
-		skb_pull_rcsum(skb, sizeof(struct ipv6hdr) + srhlen);
-		memmove(skb_network_header(skb) + srhlen,
-			skb_network_header(skb),
-			(unsigned char *)hdr - skb_network_header(skb));
-		skb->network_header += srhlen;
-		ipv6_hdr(skb)->nexthdr = nh;
-		ipv6_hdr(skb)->payload_len = htons(skb->len -
-						   sizeof(struct ipv6hdr));
-		skb_push_rcsum(skb, sizeof(struct ipv6hdr));
-	}
-
 	skb_dst_drop(skb);
 
 	ip6_route_input(skb);
@@ -453,13 +433,8 @@ looped_back:
 		}
 		ipv6_hdr(skb)->hop_limit--;
 
-		/* be sure that srh is still present before reinjecting */
-		if (!cleanup) {
-			skb_pull(skb, sizeof(struct ipv6hdr));
-			goto looped_back;
-		}
-		skb_set_transport_header(skb, sizeof(struct ipv6hdr));
-		IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr);
+		skb_pull(skb, sizeof(struct ipv6hdr));
+		goto looped_back;
 	}
 
 	dst_input(skb);
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/net/ipv6/ip6_gre.c linux-libre-4.10-rc8-gnu/net/ipv6/ip6_gre.c
--- linux-libre-4.10-rc7-gnu/net/ipv6/ip6_gre.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/net/ipv6/ip6_gre.c	2017-02-12 16:03:20.000000000 -0500
@@ -367,35 +367,37 @@ static void ip6gre_tunnel_uninit(struct
 
 
 static void ip6gre_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
-		u8 type, u8 code, int offset, __be32 info)
+		       u8 type, u8 code, int offset, __be32 info)
 {
-	const struct ipv6hdr *ipv6h = (const struct ipv6hdr *)skb->data;
-	__be16 *p = (__be16 *)(skb->data + offset);
-	int grehlen = offset + 4;
+	const struct gre_base_hdr *greh;
+	const struct ipv6hdr *ipv6h;
+	int grehlen = sizeof(*greh);
 	struct ip6_tnl *t;
+	int key_off = 0;
 	__be16 flags;
+	__be32 key;
 
-	flags = p[0];
-	if (flags&(GRE_CSUM|GRE_KEY|GRE_SEQ|GRE_ROUTING|GRE_VERSION)) {
-		if (flags&(GRE_VERSION|GRE_ROUTING))
-			return;
-		if (flags&GRE_KEY) {
-			grehlen += 4;
-			if (flags&GRE_CSUM)
-				grehlen += 4;
-		}
+	if (!pskb_may_pull(skb, offset + grehlen))
+		return;
+	greh = (const struct gre_base_hdr *)(skb->data + offset);
+	flags = greh->flags;
+	if (flags & (GRE_VERSION | GRE_ROUTING))
+		return;
+	if (flags & GRE_CSUM)
+		grehlen += 4;
+	if (flags & GRE_KEY) {
+		key_off = grehlen + offset;
+		grehlen += 4;
 	}
 
-	/* If only 8 bytes returned, keyed message will be dropped here */
-	if (!pskb_may_pull(skb, grehlen))
+	if (!pskb_may_pull(skb, offset + grehlen))
 		return;
 	ipv6h = (const struct ipv6hdr *)skb->data;
-	p = (__be16 *)(skb->data + offset);
+	greh = (const struct gre_base_hdr *)(skb->data + offset);
+	key = key_off ? *(__be32 *)(skb->data + key_off) : 0;
 
 	t = ip6gre_tunnel_lookup(skb->dev, &ipv6h->daddr, &ipv6h->saddr,
-				flags & GRE_KEY ?
-				*(((__be32 *)p) + (grehlen / 4) - 1) : 0,
-				p[1]);
+				 key, greh->protocol);
 	if (!t)
 		return;
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/net/ipv6/mcast.c linux-libre-4.10-rc8-gnu/net/ipv6/mcast.c
--- linux-libre-4.10-rc7-gnu/net/ipv6/mcast.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/net/ipv6/mcast.c	2017-02-12 16:03:20.000000000 -0500
@@ -779,6 +779,7 @@ static void mld_del_delrec(struct inet6_
 				psf->sf_crcount = im->mca_crcount;
 		}
 		in6_dev_put(pmc->idev);
+		kfree(pmc);
 	}
 	spin_unlock_bh(&im->mca_lock);
 }
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/net/ipv6/seg6_hmac.c linux-libre-4.10-rc8-gnu/net/ipv6/seg6_hmac.c
--- linux-libre-4.10-rc7-gnu/net/ipv6/seg6_hmac.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/net/ipv6/seg6_hmac.c	2017-02-12 16:03:20.000000000 -0500
@@ -174,7 +174,7 @@ int seg6_hmac_compute(struct seg6_hmac_i
 	 * hash function (RadioGatun) with up to 1216 bits
 	 */
 
-	/* saddr(16) + first_seg(1) + cleanup(1) + keyid(4) + seglist(16n) */
+	/* saddr(16) + first_seg(1) + flags(1) + keyid(4) + seglist(16n) */
 	plen = 16 + 1 + 1 + 4 + (hdr->first_segment + 1) * 16;
 
 	/* this limit allows for 14 segments */
@@ -186,7 +186,7 @@ int seg6_hmac_compute(struct seg6_hmac_i
 	 *
 	 * 1. Source IPv6 address (128 bits)
 	 * 2. first_segment value (8 bits)
-	 * 3. cleanup flag (8 bits: highest bit is cleanup value, others are 0)
+	 * 3. Flags (8 bits)
 	 * 4. HMAC Key ID (32 bits)
 	 * 5. All segments in the segments list (n * 128 bits)
 	 */
@@ -202,8 +202,8 @@ int seg6_hmac_compute(struct seg6_hmac_i
 	/* first_segment value */
 	*off++ = hdr->first_segment;
 
-	/* cleanup flag */
-	*off++ = !!(sr_has_cleanup(hdr)) << 7;
+	/* flags */
+	*off++ = hdr->flags;
 
 	/* HMAC Key ID */
 	memcpy(off, &hmackeyid, 4);
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/net/ipv6/sit.c linux-libre-4.10-rc8-gnu/net/ipv6/sit.c
--- linux-libre-4.10-rc7-gnu/net/ipv6/sit.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/net/ipv6/sit.c	2017-02-12 16:03:20.000000000 -0500
@@ -1380,6 +1380,7 @@ static int ipip6_tunnel_init(struct net_
 	err = dst_cache_init(&tunnel->dst_cache, GFP_KERNEL);
 	if (err) {
 		free_percpu(dev->tstats);
+		dev->tstats = NULL;
 		return err;
 	}
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/net/ipv6/tcp_ipv6.c linux-libre-4.10-rc8-gnu/net/ipv6/tcp_ipv6.c
--- linux-libre-4.10-rc7-gnu/net/ipv6/tcp_ipv6.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/net/ipv6/tcp_ipv6.c	2017-02-12 16:03:20.000000000 -0500
@@ -991,6 +991,16 @@ drop:
 	return 0; /* don't send reset */
 }
 
+static void tcp_v6_restore_cb(struct sk_buff *skb)
+{
+	/* We need to move header back to the beginning if xfrm6_policy_check()
+	 * and tcp_v6_fill_cb() are going to be called again.
+	 * ip6_datagram_recv_specific_ctl() also expects IP6CB to be there.
+	 */
+	memmove(IP6CB(skb), &TCP_SKB_CB(skb)->header.h6,
+		sizeof(struct inet6_skb_parm));
+}
+
 static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
 					 struct request_sock *req,
 					 struct dst_entry *dst,
@@ -1182,8 +1192,10 @@ static struct sock *tcp_v6_syn_recv_sock
 						      sk_gfp_mask(sk, GFP_ATOMIC));
 			consume_skb(ireq->pktopts);
 			ireq->pktopts = NULL;
-			if (newnp->pktoptions)
+			if (newnp->pktoptions) {
+				tcp_v6_restore_cb(newnp->pktoptions);
 				skb_set_owner_r(newnp->pktoptions, newsk);
+			}
 		}
 	}
 
@@ -1198,16 +1210,6 @@ out:
 	return NULL;
 }
 
-static void tcp_v6_restore_cb(struct sk_buff *skb)
-{
-	/* We need to move header back to the beginning if xfrm6_policy_check()
-	 * and tcp_v6_fill_cb() are going to be called again.
-	 * ip6_datagram_recv_specific_ctl() also expects IP6CB to be there.
-	 */
-	memmove(IP6CB(skb), &TCP_SKB_CB(skb)->header.h6,
-		sizeof(struct inet6_skb_parm));
-}
-
 /* The socket must have it's spinlock held when we get
  * here, unless it is a TCP_LISTEN socket.
  *
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/net/ipv6/udp.c linux-libre-4.10-rc8-gnu/net/ipv6/udp.c
--- linux-libre-4.10-rc7-gnu/net/ipv6/udp.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/net/ipv6/udp.c	2017-02-12 16:03:20.000000000 -0500
@@ -441,7 +441,7 @@ try_again:
 	return err;
 
 csum_copy_err:
-	if (!__sk_queue_drop_skb(sk, skb, flags)) {
+	if (!__sk_queue_drop_skb(sk, skb, flags, udp_skb_destructor)) {
 		if (is_udp4) {
 			UDP_INC_STATS(sock_net(sk),
 				      UDP_MIB_CSUMERRORS, is_udplite);
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/net/kcm/kcmsock.c linux-libre-4.10-rc8-gnu/net/kcm/kcmsock.c
--- linux-libre-4.10-rc7-gnu/net/kcm/kcmsock.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/net/kcm/kcmsock.c	2017-02-12 16:03:20.000000000 -0500
@@ -929,23 +929,25 @@ static int kcm_sendmsg(struct socket *so
 			goto out_error;
 	}
 
-	/* New message, alloc head skb */
-	head = alloc_skb(0, sk->sk_allocation);
-	while (!head) {
-		kcm_push(kcm);
-		err = sk_stream_wait_memory(sk, &timeo);
-		if (err)
-			goto out_error;
-
+	if (msg_data_left(msg)) {
+		/* New message, alloc head skb */
 		head = alloc_skb(0, sk->sk_allocation);
-	}
+		while (!head) {
+			kcm_push(kcm);
+			err = sk_stream_wait_memory(sk, &timeo);
+			if (err)
+				goto out_error;
 
-	skb = head;
+			head = alloc_skb(0, sk->sk_allocation);
+		}
 
-	/* Set ip_summed to CHECKSUM_UNNECESSARY to avoid calling
-	 * csum_and_copy_from_iter from skb_do_copy_data_nocache.
-	 */
-	skb->ip_summed = CHECKSUM_UNNECESSARY;
+		skb = head;
+
+		/* Set ip_summed to CHECKSUM_UNNECESSARY to avoid calling
+		 * csum_and_copy_from_iter from skb_do_copy_data_nocache.
+		 */
+		skb->ip_summed = CHECKSUM_UNNECESSARY;
+	}
 
 start:
 	while (msg_data_left(msg)) {
@@ -1018,10 +1020,12 @@ wait_for_memory:
 	if (eor) {
 		bool not_busy = skb_queue_empty(&sk->sk_write_queue);
 
-		/* Message complete, queue it on send buffer */
-		__skb_queue_tail(&sk->sk_write_queue, head);
-		kcm->seq_skb = NULL;
-		KCM_STATS_INCR(kcm->stats.tx_msgs);
+		if (head) {
+			/* Message complete, queue it on send buffer */
+			__skb_queue_tail(&sk->sk_write_queue, head);
+			kcm->seq_skb = NULL;
+			KCM_STATS_INCR(kcm->stats.tx_msgs);
+		}
 
 		if (msg->msg_flags & MSG_BATCH) {
 			kcm->tx_wait_more = true;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/net/l2tp/l2tp_core.h linux-libre-4.10-rc8-gnu/net/l2tp/l2tp_core.h
--- linux-libre-4.10-rc7-gnu/net/l2tp/l2tp_core.h	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/net/l2tp/l2tp_core.h	2017-02-12 16:03:20.000000000 -0500
@@ -263,6 +263,7 @@ int l2tp_xmit_skb(struct l2tp_session *s
 int l2tp_nl_register_ops(enum l2tp_pwtype pw_type,
 			 const struct l2tp_nl_cmd_ops *ops);
 void l2tp_nl_unregister_ops(enum l2tp_pwtype pw_type);
+int l2tp_ioctl(struct sock *sk, int cmd, unsigned long arg);
 
 /* Session reference counts. Incremented when code obtains a reference
  * to a session.
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/net/l2tp/l2tp_ip6.c linux-libre-4.10-rc8-gnu/net/l2tp/l2tp_ip6.c
--- linux-libre-4.10-rc7-gnu/net/l2tp/l2tp_ip6.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/net/l2tp/l2tp_ip6.c	2017-02-12 16:03:20.000000000 -0500
@@ -722,7 +722,7 @@ static struct proto l2tp_ip6_prot = {
 	.bind		   = l2tp_ip6_bind,
 	.connect	   = l2tp_ip6_connect,
 	.disconnect	   = l2tp_ip6_disconnect,
-	.ioctl		   = udp_ioctl,
+	.ioctl		   = l2tp_ioctl,
 	.destroy	   = l2tp_ip6_destroy_sock,
 	.setsockopt	   = ipv6_setsockopt,
 	.getsockopt	   = ipv6_getsockopt,
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/net/l2tp/l2tp_ip.c linux-libre-4.10-rc8-gnu/net/l2tp/l2tp_ip.c
--- linux-libre-4.10-rc7-gnu/net/l2tp/l2tp_ip.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/net/l2tp/l2tp_ip.c	2017-02-12 16:03:20.000000000 -0500
@@ -11,6 +11,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <asm/ioctls.h>
 #include <linux/icmp.h>
 #include <linux/module.h>
 #include <linux/skbuff.h>
@@ -553,6 +554,30 @@ out:
 	return err ? err : copied;
 }
 
+int l2tp_ioctl(struct sock *sk, int cmd, unsigned long arg)
+{
+	struct sk_buff *skb;
+	int amount;
+
+	switch (cmd) {
+	case SIOCOUTQ:
+		amount = sk_wmem_alloc_get(sk);
+		break;
+	case SIOCINQ:
+		spin_lock_bh(&sk->sk_receive_queue.lock);
+		skb = skb_peek(&sk->sk_receive_queue);
+		amount = skb ? skb->len : 0;
+		spin_unlock_bh(&sk->sk_receive_queue.lock);
+		break;
+
+	default:
+		return -ENOIOCTLCMD;
+	}
+
+	return put_user(amount, (int __user *)arg);
+}
+EXPORT_SYMBOL(l2tp_ioctl);
+
 static struct proto l2tp_ip_prot = {
 	.name		   = "L2TP/IP",
 	.owner		   = THIS_MODULE,
@@ -561,7 +586,7 @@ static struct proto l2tp_ip_prot = {
 	.bind		   = l2tp_ip_bind,
 	.connect	   = l2tp_ip_connect,
 	.disconnect	   = l2tp_ip_disconnect,
-	.ioctl		   = udp_ioctl,
+	.ioctl		   = l2tp_ioctl,
 	.destroy	   = l2tp_ip_destroy_sock,
 	.setsockopt	   = ip_setsockopt,
 	.getsockopt	   = ip_getsockopt,
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/net/mac80211/fils_aead.c linux-libre-4.10-rc8-gnu/net/mac80211/fils_aead.c
--- linux-libre-4.10-rc7-gnu/net/mac80211/fils_aead.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/net/mac80211/fils_aead.c	2017-02-12 16:03:20.000000000 -0500
@@ -124,7 +124,7 @@ static int aes_siv_encrypt(const u8 *key
 
 	/* CTR */
 
-	tfm2 = crypto_alloc_skcipher("ctr(aes)", 0, 0);
+	tfm2 = crypto_alloc_skcipher("ctr(aes)", 0, CRYPTO_ALG_ASYNC);
 	if (IS_ERR(tfm2)) {
 		kfree(tmp);
 		return PTR_ERR(tfm2);
@@ -183,7 +183,7 @@ static int aes_siv_decrypt(const u8 *key
 
 	/* CTR */
 
-	tfm2 = crypto_alloc_skcipher("ctr(aes)", 0, 0);
+	tfm2 = crypto_alloc_skcipher("ctr(aes)", 0, CRYPTO_ALG_ASYNC);
 	if (IS_ERR(tfm2))
 		return PTR_ERR(tfm2);
 	/* K2 for CTR */
@@ -272,7 +272,7 @@ int fils_encrypt_assoc_req(struct sk_buf
 	crypt_len = skb->data + skb->len - encr;
 	skb_put(skb, AES_BLOCK_SIZE);
 	return aes_siv_encrypt(assoc_data->fils_kek, assoc_data->fils_kek_len,
-			       encr, crypt_len, 1, addr, len, encr);
+			       encr, crypt_len, 5, addr, len, encr);
 }
 
 int fils_decrypt_assoc_resp(struct ieee80211_sub_if_data *sdata,
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/net/mac80211/mesh.c linux-libre-4.10-rc8-gnu/net/mac80211/mesh.c
--- linux-libre-4.10-rc7-gnu/net/mac80211/mesh.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/net/mac80211/mesh.c	2017-02-12 16:03:20.000000000 -0500
@@ -339,7 +339,7 @@ int mesh_add_vendor_ies(struct ieee80211
 	/* fast-forward to vendor IEs */
 	offset = ieee80211_ie_split_vendor(ifmsh->ie, ifmsh->ie_len, 0);
 
-	if (offset) {
+	if (offset < ifmsh->ie_len) {
 		len = ifmsh->ie_len - offset;
 		data = ifmsh->ie + offset;
 		if (skb_tailroom(skb) < len)
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/net/packet/af_packet.c linux-libre-4.10-rc8-gnu/net/packet/af_packet.c
--- linux-libre-4.10-rc7-gnu/net/packet/af_packet.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/net/packet/af_packet.c	2017-02-12 16:03:20.000000000 -0500
@@ -2755,7 +2755,7 @@ static int packet_snd(struct socket *soc
 	struct virtio_net_hdr vnet_hdr = { 0 };
 	int offset = 0;
 	struct packet_sock *po = pkt_sk(sk);
-	int hlen, tlen;
+	int hlen, tlen, linear;
 	int extra_len = 0;
 
 	/*
@@ -2816,8 +2816,9 @@ static int packet_snd(struct socket *soc
 	err = -ENOBUFS;
 	hlen = LL_RESERVED_SPACE(dev);
 	tlen = dev->needed_tailroom;
-	skb = packet_alloc_skb(sk, hlen + tlen, hlen, len,
-			       __virtio16_to_cpu(vio_le(), vnet_hdr.hdr_len),
+	linear = __virtio16_to_cpu(vio_le(), vnet_hdr.hdr_len);
+	linear = max(linear, min_t(int, len, dev->hard_header_len));
+	skb = packet_alloc_skb(sk, hlen + tlen, hlen, len, linear,
 			       msg->msg_flags & MSG_DONTWAIT, &err);
 	if (skb == NULL)
 		goto out_unlock;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/net/sctp/socket.c linux-libre-4.10-rc8-gnu/net/sctp/socket.c
--- linux-libre-4.10-rc7-gnu/net/sctp/socket.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/net/sctp/socket.c	2017-02-12 16:03:20.000000000 -0500
@@ -239,7 +239,7 @@ static struct sctp_transport *sctp_addr_
 	union sctp_addr *laddr = (union sctp_addr *)addr;
 	struct sctp_transport *transport;
 
-	if (sctp_verify_addr(sk, laddr, af->sockaddr_len))
+	if (!af || sctp_verify_addr(sk, laddr, af->sockaddr_len))
 		return NULL;
 
 	addr_asoc = sctp_endpoint_lookup_assoc(sctp_sk(sk)->ep,
@@ -7426,7 +7426,8 @@ static int sctp_wait_for_sndbuf(struct s
 		 */
 		release_sock(sk);
 		current_timeo = schedule_timeout(current_timeo);
-		BUG_ON(sk != asoc->base.sk);
+		if (sk != asoc->base.sk)
+			goto do_error;
 		lock_sock(sk);
 
 		*timeo_p = current_timeo;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/net/wireless/nl80211.c linux-libre-4.10-rc8-gnu/net/wireless/nl80211.c
--- linux-libre-4.10-rc7-gnu/net/wireless/nl80211.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/net/wireless/nl80211.c	2017-02-12 16:03:20.000000000 -0500
@@ -5916,6 +5916,7 @@ do {									    \
 			break;
 		}
 		cfg->ht_opmode = ht_opmode;
+		mask |= (1 << (NL80211_MESHCONF_HT_OPMODE - 1));
 	}
 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathToRootTimeout,
 				  1, 65535, mask,
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/security/selinux/hooks.c linux-libre-4.10-rc8-gnu/security/selinux/hooks.c
--- linux-libre-4.10-rc7-gnu/security/selinux/hooks.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/security/selinux/hooks.c	2017-02-12 16:03:20.000000000 -0500
@@ -5887,7 +5887,7 @@ static int selinux_setprocattr(struct ta
 		return error;
 
 	/* Obtain a SID for the context, if one was specified. */
-	if (size && str[1] && str[1] != '\n') {
+	if (size && str[0] && str[0] != '\n') {
 		if (str[size-1] == '\n') {
 			str[size-1] = 0;
 			size--;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/sound/core/seq/seq_memory.c linux-libre-4.10-rc8-gnu/sound/core/seq/seq_memory.c
--- linux-libre-4.10-rc7-gnu/sound/core/seq/seq_memory.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/sound/core/seq/seq_memory.c	2017-02-12 16:03:20.000000000 -0500
@@ -419,7 +419,6 @@ int snd_seq_pool_done(struct snd_seq_poo
 {
 	unsigned long flags;
 	struct snd_seq_event_cell *ptr;
-	int max_count = 5 * HZ;
 
 	if (snd_BUG_ON(!pool))
 		return -EINVAL;
@@ -432,14 +431,8 @@ int snd_seq_pool_done(struct snd_seq_poo
 	if (waitqueue_active(&pool->output_sleep))
 		wake_up(&pool->output_sleep);
 
-	while (atomic_read(&pool->counter) > 0) {
-		if (max_count == 0) {
-			pr_warn("ALSA: snd_seq_pool_done timeout: %d cells remain\n", atomic_read(&pool->counter));
-			break;
-		}
+	while (atomic_read(&pool->counter) > 0)
 		schedule_timeout_uninterruptible(1);
-		max_count--;
-	}
 	
 	/* release all resources */
 	spin_lock_irqsave(&pool->lock, flags);
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/sound/core/seq/seq_queue.c linux-libre-4.10-rc8-gnu/sound/core/seq/seq_queue.c
--- linux-libre-4.10-rc7-gnu/sound/core/seq/seq_queue.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/sound/core/seq/seq_queue.c	2017-02-12 16:03:20.000000000 -0500
@@ -181,6 +181,8 @@ void __exit snd_seq_queues_delete(void)
 	}
 }
 
+static void queue_use(struct snd_seq_queue *queue, int client, int use);
+
 /* allocate a new queue -
  * return queue index value or negative value for error
  */
@@ -192,11 +194,11 @@ int snd_seq_queue_alloc(int client, int
 	if (q == NULL)
 		return -ENOMEM;
 	q->info_flags = info_flags;
+	queue_use(q, client, 1);
 	if (queue_list_add(q) < 0) {
 		queue_delete(q);
 		return -ENOMEM;
 	}
-	snd_seq_queue_use(q->queue, client, 1); /* use this queue */
 	return q->queue;
 }
 
@@ -502,19 +504,9 @@ int snd_seq_queue_timer_set_tempo(int qu
 	return result;
 }
 
-
-/* use or unuse this queue -
- * if it is the first client, starts the timer.
- * if it is not longer used by any clients, stop the timer.
- */
-int snd_seq_queue_use(int queueid, int client, int use)
+/* use or unuse this queue */
+static void queue_use(struct snd_seq_queue *queue, int client, int use)
 {
-	struct snd_seq_queue *queue;
-
-	queue = queueptr(queueid);
-	if (queue == NULL)
-		return -EINVAL;
-	mutex_lock(&queue->timer_mutex);
 	if (use) {
 		if (!test_and_set_bit(client, queue->clients_bitmap))
 			queue->clients++;
@@ -529,6 +521,21 @@ int snd_seq_queue_use(int queueid, int c
 	} else {
 		snd_seq_timer_close(queue);
 	}
+}
+
+/* use or unuse this queue -
+ * if it is the first client, starts the timer.
+ * if it is not longer used by any clients, stop the timer.
+ */
+int snd_seq_queue_use(int queueid, int client, int use)
+{
+	struct snd_seq_queue *queue;
+
+	queue = queueptr(queueid);
+	if (queue == NULL)
+		return -EINVAL;
+	mutex_lock(&queue->timer_mutex);
+	queue_use(queue, client, use);
 	mutex_unlock(&queue->timer_mutex);
 	queuefree(queue);
 	return 0;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/sound/pci/hda/patch_hdmi.c linux-libre-4.10-rc8-gnu/sound/pci/hda/patch_hdmi.c
--- linux-libre-4.10-rc7-gnu/sound/pci/hda/patch_hdmi.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/sound/pci/hda/patch_hdmi.c	2017-02-12 16:03:20.000000000 -0500
@@ -3639,6 +3639,7 @@ HDA_CODEC_ENTRY(0x10de0070, "GPU 70 HDMI
 HDA_CODEC_ENTRY(0x10de0071, "GPU 71 HDMI/DP",	patch_nvhdmi),
 HDA_CODEC_ENTRY(0x10de0072, "GPU 72 HDMI/DP",	patch_nvhdmi),
 HDA_CODEC_ENTRY(0x10de007d, "GPU 7d HDMI/DP",	patch_nvhdmi),
+HDA_CODEC_ENTRY(0x10de0080, "GPU 80 HDMI/DP",	patch_nvhdmi),
 HDA_CODEC_ENTRY(0x10de0082, "GPU 82 HDMI/DP",	patch_nvhdmi),
 HDA_CODEC_ENTRY(0x10de0083, "GPU 83 HDMI/DP",	patch_nvhdmi),
 HDA_CODEC_ENTRY(0x10de8001, "MCP73 HDMI",	patch_nvhdmi_2ch),
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/sound/usb/line6/driver.c linux-libre-4.10-rc8-gnu/sound/usb/line6/driver.c
--- linux-libre-4.10-rc7-gnu/sound/usb/line6/driver.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/sound/usb/line6/driver.c	2017-02-12 16:03:20.000000000 -0500
@@ -754,8 +754,9 @@ int line6_probe(struct usb_interface *in
 		goto error;
 	}
 
+	line6_get_interval(line6);
+
 	if (properties->capabilities & LINE6_CAP_CONTROL) {
-		line6_get_interval(line6);
 		ret = line6_init_cap_control(line6);
 		if (ret < 0)
 			goto error;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/tools/perf/builtin-diff.c linux-libre-4.10-rc8-gnu/tools/perf/builtin-diff.c
--- linux-libre-4.10-rc7-gnu/tools/perf/builtin-diff.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/tools/perf/builtin-diff.c	2017-02-12 16:03:20.000000000 -0500
@@ -1199,7 +1199,7 @@ static int ui_init(void)
 		BUG_ON(1);
 	}
 
-	perf_hpp__register_sort_field(fmt);
+	perf_hpp__prepend_sort_field(fmt);
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/tools/perf/ui/hist.c linux-libre-4.10-rc8-gnu/tools/perf/ui/hist.c
--- linux-libre-4.10-rc7-gnu/tools/perf/ui/hist.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/tools/perf/ui/hist.c	2017-02-12 16:03:20.000000000 -0500
@@ -521,6 +521,12 @@ void perf_hpp_list__register_sort_field(
 	list_add_tail(&format->sort_list, &list->sorts);
 }
 
+void perf_hpp_list__prepend_sort_field(struct perf_hpp_list *list,
+				       struct perf_hpp_fmt *format)
+{
+	list_add(&format->sort_list, &list->sorts);
+}
+
 void perf_hpp__column_unregister(struct perf_hpp_fmt *format)
 {
 	list_del(&format->list);
@@ -560,6 +566,10 @@ void perf_hpp__setup_output_field(struct
 	perf_hpp_list__for_each_sort_list(list, fmt) {
 		struct perf_hpp_fmt *pos;
 
+		/* skip sort-only fields ("sort_compute" in perf diff) */
+		if (!fmt->entry && !fmt->color)
+			continue;
+
 		perf_hpp_list__for_each_format(list, pos) {
 			if (fmt_equal(fmt, pos))
 				goto next;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/tools/perf/util/callchain.c linux-libre-4.10-rc8-gnu/tools/perf/util/callchain.c
--- linux-libre-4.10-rc7-gnu/tools/perf/util/callchain.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/tools/perf/util/callchain.c	2017-02-12 16:03:20.000000000 -0500
@@ -437,7 +437,7 @@ fill_node(struct callchain_node *node, s
 		}
 		call->ip = cursor_node->ip;
 		call->ms.sym = cursor_node->sym;
-		call->ms.map = cursor_node->map;
+		call->ms.map = map__get(cursor_node->map);
 
 		if (cursor_node->branch) {
 			call->branch_count = 1;
@@ -477,6 +477,7 @@ add_child(struct callchain_node *parent,
 
 		list_for_each_entry_safe(call, tmp, &new->val, list) {
 			list_del(&call->list);
+			map__zput(call->ms.map);
 			free(call);
 		}
 		free(new);
@@ -761,6 +762,7 @@ merge_chain_branch(struct callchain_curs
 					list->ms.map, list->ms.sym,
 					false, NULL, 0, 0);
 		list_del(&list->list);
+		map__zput(list->ms.map);
 		free(list);
 	}
 
@@ -811,7 +813,8 @@ int callchain_cursor_append(struct callc
 	}
 
 	node->ip = ip;
-	node->map = map;
+	map__zput(node->map);
+	node->map = map__get(map);
 	node->sym = sym;
 	node->branch = branch;
 	node->nr_loop_iter = nr_loop_iter;
@@ -1142,11 +1145,13 @@ static void free_callchain_node(struct c
 
 	list_for_each_entry_safe(list, tmp, &node->parent_val, list) {
 		list_del(&list->list);
+		map__zput(list->ms.map);
 		free(list);
 	}
 
 	list_for_each_entry_safe(list, tmp, &node->val, list) {
 		list_del(&list->list);
+		map__zput(list->ms.map);
 		free(list);
 	}
 
@@ -1210,6 +1215,7 @@ int callchain_node__make_parent_list(str
 				goto out;
 			*new = *chain;
 			new->has_children = false;
+			map__get(new->ms.map);
 			list_add_tail(&new->list, &head);
 		}
 		parent = parent->parent;
@@ -1230,6 +1236,7 @@ int callchain_node__make_parent_list(str
 out:
 	list_for_each_entry_safe(chain, new, &head, list) {
 		list_del(&chain->list);
+		map__zput(chain->ms.map);
 		free(chain);
 	}
 	return -ENOMEM;
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/tools/perf/util/callchain.h linux-libre-4.10-rc8-gnu/tools/perf/util/callchain.h
--- linux-libre-4.10-rc7-gnu/tools/perf/util/callchain.h	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/tools/perf/util/callchain.h	2017-02-12 16:03:20.000000000 -0500
@@ -5,6 +5,7 @@
 #include <linux/list.h>
 #include <linux/rbtree.h>
 #include "event.h"
+#include "map.h"
 #include "symbol.h"
 
 #define HELP_PAD "\t\t\t\t"
@@ -184,8 +185,13 @@ int callchain_merge(struct callchain_cur
  */
 static inline void callchain_cursor_reset(struct callchain_cursor *cursor)
 {
+	struct callchain_cursor_node *node;
+
 	cursor->nr = 0;
 	cursor->last = &cursor->first;
+
+	for (node = cursor->first; node != NULL; node = node->next)
+		map__zput(node->map);
 }
 
 int callchain_cursor_append(struct callchain_cursor *cursor, u64 ip,
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/tools/perf/util/hist.c linux-libre-4.10-rc8-gnu/tools/perf/util/hist.c
--- linux-libre-4.10-rc7-gnu/tools/perf/util/hist.c	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/tools/perf/util/hist.c	2017-02-12 16:03:20.000000000 -0500
@@ -1,6 +1,7 @@
 #include "util.h"
 #include "build-id.h"
 #include "hist.h"
+#include "map.h"
 #include "session.h"
 #include "sort.h"
 #include "evlist.h"
@@ -1019,6 +1020,10 @@ int hist_entry_iter__add(struct hist_ent
 			 int max_stack_depth, void *arg)
 {
 	int err, err2;
+	struct map *alm = NULL;
+
+	if (al && al->map)
+		alm = map__get(al->map);
 
 	err = sample__resolve_callchain(iter->sample, &callchain_cursor, &iter->parent,
 					iter->evsel, al, max_stack_depth);
@@ -1058,6 +1063,8 @@ out:
 	if (!err)
 		err = err2;
 
+	map__put(alm);
+
 	return err;
 }
 
diff -druNp --no-dereference linux-libre-4.10-rc7-gnu/tools/perf/util/hist.h linux-libre-4.10-rc8-gnu/tools/perf/util/hist.h
--- linux-libre-4.10-rc7-gnu/tools/perf/util/hist.h	2017-02-05 18:10:58.000000000 -0500
+++ linux-libre-4.10-rc8-gnu/tools/perf/util/hist.h	2017-02-12 16:03:20.000000000 -0500
@@ -283,6 +283,8 @@ void perf_hpp_list__column_register(stru
 				    struct perf_hpp_fmt *format);
 void perf_hpp_list__register_sort_field(struct perf_hpp_list *list,
 					struct perf_hpp_fmt *format);
+void perf_hpp_list__prepend_sort_field(struct perf_hpp_list *list,
+				       struct perf_hpp_fmt *format);
 
 static inline void perf_hpp__column_register(struct perf_hpp_fmt *format)
 {
@@ -294,6 +296,11 @@ static inline void perf_hpp__register_so
 	perf_hpp_list__register_sort_field(&perf_hpp_list, format);
 }
 
+static inline void perf_hpp__prepend_sort_field(struct perf_hpp_fmt *format)
+{
+	perf_hpp_list__prepend_sort_field(&perf_hpp_list, format);
+}
+
 #define perf_hpp_list__for_each_format(_list, format) \
 	list_for_each_entry(format, &(_list)->fields, list)
 
