diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/arm/boot/dts/imx7s.dtsi linux-libre-4.9-gnu/arch/arm/boot/dts/imx7s.dtsi
--- linux-libre-4.9-rc8-gnu/arch/arm/boot/dts/imx7s.dtsi	2016-12-04 17:40:15.000000000 -0500
+++ linux-libre-4.9-gnu/arch/arm/boot/dts/imx7s.dtsi	2016-12-11 17:43:34.000000000 -0500
@@ -643,9 +643,8 @@
 				reg = <0x30730000 0x10000>;
 				interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clks IMX7D_LCDIF_PIXEL_ROOT_CLK>,
-					<&clks IMX7D_CLK_DUMMY>,
-					<&clks IMX7D_CLK_DUMMY>;
-				clock-names = "pix", "axi", "disp_axi";
+					<&clks IMX7D_LCDIF_PIXEL_ROOT_CLK>;
+				clock-names = "pix", "axi";
 				status = "disabled";
 			};
 		};
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/arm/boot/dts/orion5x-linkstation-lsgl.dts linux-libre-4.9-gnu/arch/arm/boot/dts/orion5x-linkstation-lsgl.dts
--- linux-libre-4.9-rc8-gnu/arch/arm/boot/dts/orion5x-linkstation-lsgl.dts	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/arm/boot/dts/orion5x-linkstation-lsgl.dts	2016-12-11 14:17:54.000000000 -0500
@@ -82,6 +82,10 @@
 	gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
 };
 
+&sata {
+	nr-ports = <2>;
+};
+
 &ehci1 {
 	status = "okay";
 };
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/arm/boot/dts/sun8i-h3.dtsi linux-libre-4.9-gnu/arch/arm/boot/dts/sun8i-h3.dtsi
--- linux-libre-4.9-rc8-gnu/arch/arm/boot/dts/sun8i-h3.dtsi	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/arm/boot/dts/sun8i-h3.dtsi	2016-12-11 14:17:54.000000000 -0500
@@ -410,7 +410,7 @@
 			};
 
 			uart3_pins: uart3 {
-				allwinner,pins = "PG13", "PG14";
+				allwinner,pins = "PA13", "PA14";
 				allwinner,function = "uart3";
 				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/m68k/configs/amiga_defconfig linux-libre-4.9-gnu/arch/m68k/configs/amiga_defconfig
--- linux-libre-4.9-rc8-gnu/arch/m68k/configs/amiga_defconfig	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/m68k/configs/amiga_defconfig	2016-12-11 14:17:54.000000000 -0500
@@ -95,9 +95,10 @@ CONFIG_NF_TABLES_INET=m
 CONFIG_NF_TABLES_NETDEV=m
 CONFIG_NFT_EXTHDR=m
 CONFIG_NFT_META=m
+CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
-CONFIG_NFT_RBTREE=m
-CONFIG_NFT_HASH=m
+CONFIG_NFT_SET_RBTREE=m
+CONFIG_NFT_SET_HASH=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -105,8 +106,10 @@ CONFIG_NFT_MASQ=m
 CONFIG_NFT_REDIR=m
 CONFIG_NFT_NAT=m
 CONFIG_NFT_QUEUE=m
+CONFIG_NFT_QUOTA=m
 CONFIG_NFT_REJECT=m
 CONFIG_NFT_COMPAT=m
+CONFIG_NFT_HASH=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NETFILTER_XT_SET=m
@@ -366,6 +369,7 @@ CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_AMAZON is not set
 CONFIG_A2065=y
 CONFIG_ARIADNE=y
 # CONFIG_NET_VENDOR_ARC is not set
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/m68k/configs/apollo_defconfig linux-libre-4.9-gnu/arch/m68k/configs/apollo_defconfig
--- linux-libre-4.9-rc8-gnu/arch/m68k/configs/apollo_defconfig	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/m68k/configs/apollo_defconfig	2016-12-11 14:17:54.000000000 -0500
@@ -93,9 +93,10 @@ CONFIG_NF_TABLES_INET=m
 CONFIG_NF_TABLES_NETDEV=m
 CONFIG_NFT_EXTHDR=m
 CONFIG_NFT_META=m
+CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
-CONFIG_NFT_RBTREE=m
-CONFIG_NFT_HASH=m
+CONFIG_NFT_SET_RBTREE=m
+CONFIG_NFT_SET_HASH=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -103,8 +104,10 @@ CONFIG_NFT_MASQ=m
 CONFIG_NFT_REDIR=m
 CONFIG_NFT_NAT=m
 CONFIG_NFT_QUEUE=m
+CONFIG_NFT_QUOTA=m
 CONFIG_NFT_REJECT=m
 CONFIG_NFT_COMPAT=m
+CONFIG_NFT_HASH=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NETFILTER_XT_SET=m
@@ -347,6 +350,7 @@ CONFIG_MACSEC=m
 CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
+# CONFIG_NET_VENDOR_AMAZON is not set
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/m68k/configs/atari_defconfig linux-libre-4.9-gnu/arch/m68k/configs/atari_defconfig
--- linux-libre-4.9-rc8-gnu/arch/m68k/configs/atari_defconfig	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/m68k/configs/atari_defconfig	2016-12-11 14:17:54.000000000 -0500
@@ -93,9 +93,10 @@ CONFIG_NF_TABLES_INET=m
 CONFIG_NF_TABLES_NETDEV=m
 CONFIG_NFT_EXTHDR=m
 CONFIG_NFT_META=m
+CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
-CONFIG_NFT_RBTREE=m
-CONFIG_NFT_HASH=m
+CONFIG_NFT_SET_RBTREE=m
+CONFIG_NFT_SET_HASH=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -103,8 +104,10 @@ CONFIG_NFT_MASQ=m
 CONFIG_NFT_REDIR=m
 CONFIG_NFT_NAT=m
 CONFIG_NFT_QUEUE=m
+CONFIG_NFT_QUOTA=m
 CONFIG_NFT_REJECT=m
 CONFIG_NFT_COMPAT=m
+CONFIG_NFT_HASH=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NETFILTER_XT_SET=m
@@ -356,6 +359,7 @@ CONFIG_MACSEC=m
 CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
+# CONFIG_NET_VENDOR_AMAZON is not set
 CONFIG_ATARILANCE=y
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/m68k/configs/bvme6000_defconfig linux-libre-4.9-gnu/arch/m68k/configs/bvme6000_defconfig
--- linux-libre-4.9-rc8-gnu/arch/m68k/configs/bvme6000_defconfig	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/m68k/configs/bvme6000_defconfig	2016-12-11 14:17:54.000000000 -0500
@@ -91,9 +91,10 @@ CONFIG_NF_TABLES_INET=m
 CONFIG_NF_TABLES_NETDEV=m
 CONFIG_NFT_EXTHDR=m
 CONFIG_NFT_META=m
+CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
-CONFIG_NFT_RBTREE=m
-CONFIG_NFT_HASH=m
+CONFIG_NFT_SET_RBTREE=m
+CONFIG_NFT_SET_HASH=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -101,8 +102,10 @@ CONFIG_NFT_MASQ=m
 CONFIG_NFT_REDIR=m
 CONFIG_NFT_NAT=m
 CONFIG_NFT_QUEUE=m
+CONFIG_NFT_QUOTA=m
 CONFIG_NFT_REJECT=m
 CONFIG_NFT_COMPAT=m
+CONFIG_NFT_HASH=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NETFILTER_XT_SET=m
@@ -346,6 +349,7 @@ CONFIG_MACSEC=m
 CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
+# CONFIG_NET_VENDOR_AMAZON is not set
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/m68k/configs/hp300_defconfig linux-libre-4.9-gnu/arch/m68k/configs/hp300_defconfig
--- linux-libre-4.9-rc8-gnu/arch/m68k/configs/hp300_defconfig	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/m68k/configs/hp300_defconfig	2016-12-11 14:17:54.000000000 -0500
@@ -93,9 +93,10 @@ CONFIG_NF_TABLES_INET=m
 CONFIG_NF_TABLES_NETDEV=m
 CONFIG_NFT_EXTHDR=m
 CONFIG_NFT_META=m
+CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
-CONFIG_NFT_RBTREE=m
-CONFIG_NFT_HASH=m
+CONFIG_NFT_SET_RBTREE=m
+CONFIG_NFT_SET_HASH=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -103,8 +104,10 @@ CONFIG_NFT_MASQ=m
 CONFIG_NFT_REDIR=m
 CONFIG_NFT_NAT=m
 CONFIG_NFT_QUEUE=m
+CONFIG_NFT_QUOTA=m
 CONFIG_NFT_REJECT=m
 CONFIG_NFT_COMPAT=m
+CONFIG_NFT_HASH=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NETFILTER_XT_SET=m
@@ -347,6 +350,7 @@ CONFIG_MACSEC=m
 CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
+# CONFIG_NET_VENDOR_AMAZON is not set
 CONFIG_HPLANCE=y
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/m68k/configs/mac_defconfig linux-libre-4.9-gnu/arch/m68k/configs/mac_defconfig
--- linux-libre-4.9-rc8-gnu/arch/m68k/configs/mac_defconfig	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/m68k/configs/mac_defconfig	2016-12-11 14:17:54.000000000 -0500
@@ -92,9 +92,10 @@ CONFIG_NF_TABLES_INET=m
 CONFIG_NF_TABLES_NETDEV=m
 CONFIG_NFT_EXTHDR=m
 CONFIG_NFT_META=m
+CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
-CONFIG_NFT_RBTREE=m
-CONFIG_NFT_HASH=m
+CONFIG_NFT_SET_RBTREE=m
+CONFIG_NFT_SET_HASH=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -102,8 +103,10 @@ CONFIG_NFT_MASQ=m
 CONFIG_NFT_REDIR=m
 CONFIG_NFT_NAT=m
 CONFIG_NFT_QUEUE=m
+CONFIG_NFT_QUOTA=m
 CONFIG_NFT_REJECT=m
 CONFIG_NFT_COMPAT=m
+CONFIG_NFT_HASH=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NETFILTER_XT_SET=m
@@ -363,6 +366,7 @@ CONFIG_MACSEC=m
 CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
+# CONFIG_NET_VENDOR_AMAZON is not set
 CONFIG_MACMACE=y
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/m68k/configs/multi_defconfig linux-libre-4.9-gnu/arch/m68k/configs/multi_defconfig
--- linux-libre-4.9-rc8-gnu/arch/m68k/configs/multi_defconfig	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/m68k/configs/multi_defconfig	2016-12-11 14:17:54.000000000 -0500
@@ -102,9 +102,10 @@ CONFIG_NF_TABLES_INET=m
 CONFIG_NF_TABLES_NETDEV=m
 CONFIG_NFT_EXTHDR=m
 CONFIG_NFT_META=m
+CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
-CONFIG_NFT_RBTREE=m
-CONFIG_NFT_HASH=m
+CONFIG_NFT_SET_RBTREE=m
+CONFIG_NFT_SET_HASH=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -112,8 +113,10 @@ CONFIG_NFT_MASQ=m
 CONFIG_NFT_REDIR=m
 CONFIG_NFT_NAT=m
 CONFIG_NFT_QUEUE=m
+CONFIG_NFT_QUOTA=m
 CONFIG_NFT_REJECT=m
 CONFIG_NFT_COMPAT=m
+CONFIG_NFT_HASH=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NETFILTER_XT_SET=m
@@ -397,6 +400,7 @@ CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_AMAZON is not set
 CONFIG_A2065=y
 CONFIG_ARIADNE=y
 CONFIG_ATARILANCE=y
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/m68k/configs/mvme147_defconfig linux-libre-4.9-gnu/arch/m68k/configs/mvme147_defconfig
--- linux-libre-4.9-rc8-gnu/arch/m68k/configs/mvme147_defconfig	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/m68k/configs/mvme147_defconfig	2016-12-11 14:17:54.000000000 -0500
@@ -90,9 +90,10 @@ CONFIG_NF_TABLES_INET=m
 CONFIG_NF_TABLES_NETDEV=m
 CONFIG_NFT_EXTHDR=m
 CONFIG_NFT_META=m
+CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
-CONFIG_NFT_RBTREE=m
-CONFIG_NFT_HASH=m
+CONFIG_NFT_SET_RBTREE=m
+CONFIG_NFT_SET_HASH=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -100,8 +101,10 @@ CONFIG_NFT_MASQ=m
 CONFIG_NFT_REDIR=m
 CONFIG_NFT_NAT=m
 CONFIG_NFT_QUEUE=m
+CONFIG_NFT_QUOTA=m
 CONFIG_NFT_REJECT=m
 CONFIG_NFT_COMPAT=m
+CONFIG_NFT_HASH=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NETFILTER_XT_SET=m
@@ -345,6 +348,7 @@ CONFIG_MACSEC=m
 CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
+# CONFIG_NET_VENDOR_AMAZON is not set
 CONFIG_MVME147_NET=y
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/m68k/configs/mvme16x_defconfig linux-libre-4.9-gnu/arch/m68k/configs/mvme16x_defconfig
--- linux-libre-4.9-rc8-gnu/arch/m68k/configs/mvme16x_defconfig	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/m68k/configs/mvme16x_defconfig	2016-12-11 14:17:54.000000000 -0500
@@ -91,9 +91,10 @@ CONFIG_NF_TABLES_INET=m
 CONFIG_NF_TABLES_NETDEV=m
 CONFIG_NFT_EXTHDR=m
 CONFIG_NFT_META=m
+CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
-CONFIG_NFT_RBTREE=m
-CONFIG_NFT_HASH=m
+CONFIG_NFT_SET_RBTREE=m
+CONFIG_NFT_SET_HASH=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -101,8 +102,10 @@ CONFIG_NFT_MASQ=m
 CONFIG_NFT_REDIR=m
 CONFIG_NFT_NAT=m
 CONFIG_NFT_QUEUE=m
+CONFIG_NFT_QUOTA=m
 CONFIG_NFT_REJECT=m
 CONFIG_NFT_COMPAT=m
+CONFIG_NFT_HASH=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NETFILTER_XT_SET=m
@@ -346,6 +349,7 @@ CONFIG_MACSEC=m
 CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
+# CONFIG_NET_VENDOR_AMAZON is not set
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/m68k/configs/q40_defconfig linux-libre-4.9-gnu/arch/m68k/configs/q40_defconfig
--- linux-libre-4.9-rc8-gnu/arch/m68k/configs/q40_defconfig	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/m68k/configs/q40_defconfig	2016-12-11 14:17:54.000000000 -0500
@@ -91,9 +91,10 @@ CONFIG_NF_TABLES_INET=m
 CONFIG_NF_TABLES_NETDEV=m
 CONFIG_NFT_EXTHDR=m
 CONFIG_NFT_META=m
+CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
-CONFIG_NFT_RBTREE=m
-CONFIG_NFT_HASH=m
+CONFIG_NFT_SET_RBTREE=m
+CONFIG_NFT_SET_HASH=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -101,8 +102,10 @@ CONFIG_NFT_MASQ=m
 CONFIG_NFT_REDIR=m
 CONFIG_NFT_NAT=m
 CONFIG_NFT_QUEUE=m
+CONFIG_NFT_QUOTA=m
 CONFIG_NFT_REJECT=m
 CONFIG_NFT_COMPAT=m
+CONFIG_NFT_HASH=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NETFILTER_XT_SET=m
@@ -353,6 +356,7 @@ CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_AMAZON is not set
 # CONFIG_NET_VENDOR_AMD is not set
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/m68k/configs/sun3_defconfig linux-libre-4.9-gnu/arch/m68k/configs/sun3_defconfig
--- linux-libre-4.9-rc8-gnu/arch/m68k/configs/sun3_defconfig	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/m68k/configs/sun3_defconfig	2016-12-11 14:17:54.000000000 -0500
@@ -88,9 +88,10 @@ CONFIG_NF_TABLES_INET=m
 CONFIG_NF_TABLES_NETDEV=m
 CONFIG_NFT_EXTHDR=m
 CONFIG_NFT_META=m
+CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
-CONFIG_NFT_RBTREE=m
-CONFIG_NFT_HASH=m
+CONFIG_NFT_SET_RBTREE=m
+CONFIG_NFT_SET_HASH=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -98,8 +99,10 @@ CONFIG_NFT_MASQ=m
 CONFIG_NFT_REDIR=m
 CONFIG_NFT_NAT=m
 CONFIG_NFT_QUEUE=m
+CONFIG_NFT_QUOTA=m
 CONFIG_NFT_REJECT=m
 CONFIG_NFT_COMPAT=m
+CONFIG_NFT_HASH=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NETFILTER_XT_SET=m
@@ -343,6 +346,7 @@ CONFIG_MACSEC=m
 CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
+# CONFIG_NET_VENDOR_AMAZON is not set
 CONFIG_SUN3LANCE=y
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/m68k/configs/sun3x_defconfig linux-libre-4.9-gnu/arch/m68k/configs/sun3x_defconfig
--- linux-libre-4.9-rc8-gnu/arch/m68k/configs/sun3x_defconfig	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/m68k/configs/sun3x_defconfig	2016-12-11 14:17:54.000000000 -0500
@@ -88,9 +88,10 @@ CONFIG_NF_TABLES_INET=m
 CONFIG_NF_TABLES_NETDEV=m
 CONFIG_NFT_EXTHDR=m
 CONFIG_NFT_META=m
+CONFIG_NFT_NUMGEN=m
 CONFIG_NFT_CT=m
-CONFIG_NFT_RBTREE=m
-CONFIG_NFT_HASH=m
+CONFIG_NFT_SET_RBTREE=m
+CONFIG_NFT_SET_HASH=m
 CONFIG_NFT_COUNTER=m
 CONFIG_NFT_LOG=m
 CONFIG_NFT_LIMIT=m
@@ -98,8 +99,10 @@ CONFIG_NFT_MASQ=m
 CONFIG_NFT_REDIR=m
 CONFIG_NFT_NAT=m
 CONFIG_NFT_QUEUE=m
+CONFIG_NFT_QUOTA=m
 CONFIG_NFT_REJECT=m
 CONFIG_NFT_COMPAT=m
+CONFIG_NFT_HASH=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NETFILTER_XT_SET=m
@@ -343,6 +346,7 @@ CONFIG_MACSEC=m
 CONFIG_NETCONSOLE=m
 CONFIG_NETCONSOLE_DYNAMIC=y
 CONFIG_VETH=m
+# CONFIG_NET_VENDOR_AMAZON is not set
 CONFIG_SUN3LANCE=y
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_CADENCE is not set
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/m68k/include/asm/delay.h linux-libre-4.9-gnu/arch/m68k/include/asm/delay.h
--- linux-libre-4.9-rc8-gnu/arch/m68k/include/asm/delay.h	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/m68k/include/asm/delay.h	2016-12-11 14:17:54.000000000 -0500
@@ -114,6 +114,6 @@ static inline void __udelay(unsigned lon
  */
 #define	HZSCALE		(268435456 / (1000000 / HZ))
 
-#define ndelay(n) __delay(DIV_ROUND_UP((n) * ((((HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6), 1000));
+#define ndelay(n) __delay(DIV_ROUND_UP((n) * ((((HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6), 1000))
 
 #endif /* defined(_M68K_DELAY_H) */
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/mips/kernel/time.c linux-libre-4.9-gnu/arch/mips/kernel/time.c
--- linux-libre-4.9-rc8-gnu/arch/mips/kernel/time.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/mips/kernel/time.c	2016-12-11 14:17:54.000000000 -0500
@@ -36,7 +36,7 @@ EXPORT_SYMBOL(rtc_lock);
 
 int __weak rtc_mips_set_time(unsigned long sec)
 {
-	return 0;
+	return -ENODEV;
 }
 
 int __weak rtc_mips_set_mmss(unsigned long nowtime)
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/mips/lantiq/falcon/sysctrl.c linux-libre-4.9-gnu/arch/mips/lantiq/falcon/sysctrl.c
--- linux-libre-4.9-rc8-gnu/arch/mips/lantiq/falcon/sysctrl.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/mips/lantiq/falcon/sysctrl.c	2016-12-11 14:17:54.000000000 -0500
@@ -24,7 +24,7 @@
 
 /* GPE frequency selection */
 #define GPPC_OFFSET		24
-#define GPEFREQ_MASK		0x00000C0
+#define GPEFREQ_MASK		0x0000C00
 #define GPEFREQ_OFFSET		10
 /* Clock status register */
 #define SYSCTL_CLKS		0x0000
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/parisc/include/asm/pgtable.h linux-libre-4.9-gnu/arch/parisc/include/asm/pgtable.h
--- linux-libre-4.9-rc8-gnu/arch/parisc/include/asm/pgtable.h	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/parisc/include/asm/pgtable.h	2016-12-11 14:17:54.000000000 -0500
@@ -65,9 +65,9 @@ static inline void purge_tlb_entries(str
 		unsigned long flags;				\
 		spin_lock_irqsave(&pa_tlb_lock, flags);		\
 		old_pte = *ptep;				\
-		set_pte(ptep, pteval);				\
 		if (pte_inserted(old_pte))			\
 			purge_tlb_entries(mm, addr);		\
+		set_pte(ptep, pteval);				\
 		spin_unlock_irqrestore(&pa_tlb_lock, flags);	\
 	} while (0)
 
@@ -478,8 +478,8 @@ static inline int ptep_test_and_clear_yo
 		spin_unlock_irqrestore(&pa_tlb_lock, flags);
 		return 0;
 	}
-	set_pte(ptep, pte_mkold(pte));
 	purge_tlb_entries(vma->vm_mm, addr);
+	set_pte(ptep, pte_mkold(pte));
 	spin_unlock_irqrestore(&pa_tlb_lock, flags);
 	return 1;
 }
@@ -492,9 +492,9 @@ static inline pte_t ptep_get_and_clear(s
 
 	spin_lock_irqsave(&pa_tlb_lock, flags);
 	old_pte = *ptep;
-	set_pte(ptep, __pte(0));
 	if (pte_inserted(old_pte))
 		purge_tlb_entries(mm, addr);
+	set_pte(ptep, __pte(0));
 	spin_unlock_irqrestore(&pa_tlb_lock, flags);
 
 	return old_pte;
@@ -504,8 +504,8 @@ static inline void ptep_set_wrprotect(st
 {
 	unsigned long flags;
 	spin_lock_irqsave(&pa_tlb_lock, flags);
-	set_pte(ptep, pte_wrprotect(*ptep));
 	purge_tlb_entries(mm, addr);
+	set_pte(ptep, pte_wrprotect(*ptep));
 	spin_unlock_irqrestore(&pa_tlb_lock, flags);
 }
 
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/parisc/kernel/cache.c linux-libre-4.9-gnu/arch/parisc/kernel/cache.c
--- linux-libre-4.9-rc8-gnu/arch/parisc/kernel/cache.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/parisc/kernel/cache.c	2016-12-11 14:17:54.000000000 -0500
@@ -393,6 +393,15 @@ void __init parisc_setup_cache_timing(vo
 
 	/* calculate TLB flush threshold */
 
+	/* On SMP machines, skip the TLB measure of kernel text which
+	 * has been mapped as huge pages. */
+	if (num_online_cpus() > 1 && !parisc_requires_coherency()) {
+		threshold = max(cache_info.it_size, cache_info.dt_size);
+		threshold *= PAGE_SIZE;
+		threshold /= num_online_cpus();
+		goto set_tlb_threshold;
+	}
+
 	alltime = mfctl(16);
 	flush_tlb_all();
 	alltime = mfctl(16) - alltime;
@@ -411,6 +420,8 @@ void __init parisc_setup_cache_timing(vo
 		alltime, size, rangetime);
 
 	threshold = PAGE_ALIGN(num_online_cpus() * size * alltime / rangetime);
+
+set_tlb_threshold:
 	if (threshold)
 		parisc_tlb_flush_threshold = threshold;
 	printk(KERN_INFO "TLB flush threshold set to %lu KiB\n",
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/parisc/kernel/pacache.S linux-libre-4.9-gnu/arch/parisc/kernel/pacache.S
--- linux-libre-4.9-rc8-gnu/arch/parisc/kernel/pacache.S	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/parisc/kernel/pacache.S	2016-12-11 14:17:54.000000000 -0500
@@ -892,19 +892,10 @@ ENTRY_CFI(flush_dcache_page_asm)
 	fdc,m		r31(%r28)
 	fdc,m		r31(%r28)
 	fdc,m		r31(%r28)
-	cmpb,COND(<<)		%r28, %r25,1b
+	cmpb,COND(<<)	%r28, %r25,1b
 	fdc,m		r31(%r28)
 
 	sync
-
-#ifdef CONFIG_PA20
-	pdtlb,l		%r0(%r25)
-#else
-	tlb_lock	%r20,%r21,%r22
-	pdtlb		%r0(%r25)
-	tlb_unlock	%r20,%r21,%r22
-#endif
-
 	bv		%r0(%r2)
 	nop
 	.exit
@@ -979,17 +970,6 @@ ENTRY_CFI(flush_icache_page_asm)
 	fic,m		%r31(%sr4,%r28)
 
 	sync
-
-#ifdef CONFIG_PA20
-	pdtlb,l		%r0(%r28)
-	pitlb,l         %r0(%sr4,%r25)
-#else
-	tlb_lock        %r20,%r21,%r22
-	pdtlb		%r0(%r28)
-	pitlb           %r0(%sr4,%r25)
-	tlb_unlock      %r20,%r21,%r22
-#endif
-
 	bv		%r0(%r2)
 	nop
 	.exit
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/powerpc/boot/Makefile linux-libre-4.9-gnu/arch/powerpc/boot/Makefile
--- linux-libre-4.9-rc8-gnu/arch/powerpc/boot/Makefile	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/powerpc/boot/Makefile	2016-12-11 14:17:54.000000000 -0500
@@ -100,7 +100,8 @@ src-wlib-y := string.S crt0.S crtsavres.
 		ns16550.c serial.c simple_alloc.c div64.S util.S \
 		elf_util.c $(zlib-y) devtree.c stdlib.c \
 		oflib.c ofconsole.c cuboot.c mpsc.c cpm-serial.c \
-		uartlite.c mpc52xx-psc.c opal.c opal-calls.S
+		uartlite.c mpc52xx-psc.c opal.c
+src-wlib-$(CONFIG_PPC64_BOOT_WRAPPER) +=  opal-calls.S
 src-wlib-$(CONFIG_40x) += 4xx.c planetcore.c
 src-wlib-$(CONFIG_44x) += 4xx.c ebony.c bamboo.c
 src-wlib-$(CONFIG_8xx) += mpc8xx.c planetcore.c fsl-soc.c
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/powerpc/boot/opal.c linux-libre-4.9-gnu/arch/powerpc/boot/opal.c
--- linux-libre-4.9-rc8-gnu/arch/powerpc/boot/opal.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/powerpc/boot/opal.c	2016-12-11 14:17:54.000000000 -0500
@@ -13,7 +13,7 @@
 #include <libfdt.h>
 #include "../include/asm/opal-api.h"
 
-#ifdef __powerpc64__
+#ifdef CONFIG_PPC64_BOOT_WRAPPER
 
 /* Global OPAL struct used by opal-call.S */
 struct opal {
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/powerpc/kernel/eeh_driver.c linux-libre-4.9-gnu/arch/powerpc/kernel/eeh_driver.c
--- linux-libre-4.9-rc8-gnu/arch/powerpc/kernel/eeh_driver.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/powerpc/kernel/eeh_driver.c	2016-12-11 14:17:54.000000000 -0500
@@ -671,8 +671,10 @@ static int eeh_reset_device(struct eeh_p
 
 	/* Clear frozen state */
 	rc = eeh_clear_pe_frozen_state(pe, false);
-	if (rc)
+	if (rc) {
+		pci_unlock_rescan_remove();
 		return rc;
+	}
 
 	/* Give the system 5 seconds to finish running the user-space
 	 * hotplug shutdown scripts, e.g. ifdown for ethernet.  Yes,
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/powerpc/kernel/vmlinux.lds.S linux-libre-4.9-gnu/arch/powerpc/kernel/vmlinux.lds.S
--- linux-libre-4.9-rc8-gnu/arch/powerpc/kernel/vmlinux.lds.S	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/powerpc/kernel/vmlinux.lds.S	2016-12-11 14:17:54.000000000 -0500
@@ -94,8 +94,17 @@ SECTIONS
 	 * detected, and will result in a crash at boot due to offsets being
 	 * wrong.
 	 */
+#ifdef CONFIG_PPC64
+	/*
+	 * BLOCK(0) overrides the default output section alignment because
+	 * this needs to start right after .head.text in order for fixed
+	 * section placement to work.
+	 */
+	.text BLOCK(0) : AT(ADDR(.text) - LOAD_OFFSET) {
+#else
 	.text : AT(ADDR(.text) - LOAD_OFFSET) {
 		ALIGN_FUNCTION();
+#endif
 		/* careful! __ftr_alt_* sections need to be close to .text */
 		*(.text .fixup __ftr_alt_* .ref.text)
 		SCHED_TEXT
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/powerpc/mm/hash64_4k.c linux-libre-4.9-gnu/arch/powerpc/mm/hash64_4k.c
--- linux-libre-4.9-rc8-gnu/arch/powerpc/mm/hash64_4k.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/powerpc/mm/hash64_4k.c	2016-12-11 14:17:54.000000000 -0500
@@ -55,7 +55,7 @@ int __hash_page_4K(unsigned long ea, uns
 	 */
 	rflags = htab_convert_pte_flags(new_pte);
 
-	if (!cpu_has_feature(CPU_FTR_NOEXECUTE) &&
+	if (cpu_has_feature(CPU_FTR_NOEXECUTE) &&
 	    !cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
 		rflags = hash_page_do_lazy_icache(rflags, __pte(old_pte), trap);
 
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/powerpc/mm/hash64_64k.c linux-libre-4.9-gnu/arch/powerpc/mm/hash64_64k.c
--- linux-libre-4.9-rc8-gnu/arch/powerpc/mm/hash64_64k.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/powerpc/mm/hash64_64k.c	2016-12-11 14:17:54.000000000 -0500
@@ -87,7 +87,7 @@ int __hash_page_4K(unsigned long ea, uns
 	subpg_pte = new_pte & ~subpg_prot;
 	rflags = htab_convert_pte_flags(subpg_pte);
 
-	if (!cpu_has_feature(CPU_FTR_NOEXECUTE) &&
+	if (cpu_has_feature(CPU_FTR_NOEXECUTE) &&
 	    !cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) {
 
 		/*
@@ -258,7 +258,7 @@ int __hash_page_64K(unsigned long ea, un
 
 	rflags = htab_convert_pte_flags(new_pte);
 
-	if (!cpu_has_feature(CPU_FTR_NOEXECUTE) &&
+	if (cpu_has_feature(CPU_FTR_NOEXECUTE) &&
 	    !cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
 		rflags = hash_page_do_lazy_icache(rflags, __pte(old_pte), trap);
 
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/x86/events/core.c linux-libre-4.9-gnu/arch/x86/events/core.c
--- linux-libre-4.9-rc8-gnu/arch/x86/events/core.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/x86/events/core.c	2016-12-11 14:17:54.000000000 -0500
@@ -69,7 +69,7 @@ u64 x86_perf_event_update(struct perf_ev
 	int shift = 64 - x86_pmu.cntval_bits;
 	u64 prev_raw_count, new_raw_count;
 	int idx = hwc->idx;
-	s64 delta;
+	u64 delta;
 
 	if (idx == INTEL_PMC_IDX_FIXED_BTS)
 		return 0;
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/x86/events/intel/core.c linux-libre-4.9-gnu/arch/x86/events/intel/core.c
--- linux-libre-4.9-rc8-gnu/arch/x86/events/intel/core.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/x86/events/intel/core.c	2016-12-11 14:17:54.000000000 -0500
@@ -4034,7 +4034,7 @@ __init int intel_pmu_init(void)
 
 	/* Support full width counters using alternative MSR range */
 	if (x86_pmu.intel_cap.full_width_write) {
-		x86_pmu.max_period = x86_pmu.cntval_mask;
+		x86_pmu.max_period = x86_pmu.cntval_mask >> 1;
 		x86_pmu.perfctr = MSR_IA32_PMC0;
 		pr_cont("full-width counters, ");
 	}
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/x86/events/intel/cstate.c linux-libre-4.9-gnu/arch/x86/events/intel/cstate.c
--- linux-libre-4.9-rc8-gnu/arch/x86/events/intel/cstate.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/x86/events/intel/cstate.c	2016-12-11 14:17:54.000000000 -0500
@@ -540,6 +540,7 @@ static const struct x86_cpu_id intel_cst
 	X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE_DESKTOP, snb_cstates),
 
 	X86_CSTATES_MODEL(INTEL_FAM6_XEON_PHI_KNL, knl_cstates),
+	X86_CSTATES_MODEL(INTEL_FAM6_XEON_PHI_KNM, knl_cstates),
 	{ },
 };
 MODULE_DEVICE_TABLE(x86cpu, intel_cstates_match);
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/x86/include/asm/compat.h linux-libre-4.9-gnu/arch/x86/include/asm/compat.h
--- linux-libre-4.9-rc8-gnu/arch/x86/include/asm/compat.h	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/x86/include/asm/compat.h	2016-12-11 14:17:54.000000000 -0500
@@ -272,7 +272,6 @@ struct compat_shmid64_ds {
 /*
  * The type of struct elf_prstatus.pr_reg in compatible core dumps.
  */
-#ifdef CONFIG_X86_X32_ABI
 typedef struct user_regs_struct compat_elf_gregset_t;
 
 /* Full regset -- prstatus on x32, otherwise on ia32 */
@@ -281,10 +280,9 @@ typedef struct user_regs_struct compat_e
   do { *(int *) (((void *) &((S)->pr_reg)) + R) = (V); } \
   while (0)
 
+#ifdef CONFIG_X86_X32_ABI
 #define COMPAT_USE_64BIT_TIME \
 	(!!(task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT))
-#else
-typedef struct user_regs_struct32 compat_elf_gregset_t;
 #endif
 
 /*
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/x86/kernel/apic/x2apic_uv_x.c linux-libre-4.9-gnu/arch/x86/kernel/apic/x2apic_uv_x.c
--- linux-libre-4.9-rc8-gnu/arch/x86/kernel/apic/x2apic_uv_x.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/x86/kernel/apic/x2apic_uv_x.c	2016-12-11 14:17:54.000000000 -0500
@@ -815,9 +815,9 @@ static __init void map_mmioh_high_uv3(in
 				l = li;
 			}
 			addr1 = (base << shift) +
-				f * (unsigned long)(1 << m_io);
+				f * (1ULL << m_io);
 			addr2 = (base << shift) +
-				(l + 1) * (unsigned long)(1 << m_io);
+				(l + 1) * (1ULL << m_io);
 			pr_info("UV: %s[%03d..%03d] NASID 0x%04x ADDR 0x%016lx - 0x%016lx\n",
 				id, fi, li, lnasid, addr1, addr2);
 			if (max_io < l)
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/x86/kernel/unwind_guess.c linux-libre-4.9-gnu/arch/x86/kernel/unwind_guess.c
--- linux-libre-4.9-rc8-gnu/arch/x86/kernel/unwind_guess.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/x86/kernel/unwind_guess.c	2016-12-11 14:17:54.000000000 -0500
@@ -7,11 +7,13 @@
 
 unsigned long unwind_get_return_address(struct unwind_state *state)
 {
-	unsigned long addr = READ_ONCE_NOCHECK(*state->sp);
+	unsigned long addr;
 
 	if (unwind_done(state))
 		return 0;
 
+	addr = READ_ONCE_NOCHECK(*state->sp);
+
 	return ftrace_graph_ret_addr(state->task, &state->graph_idx,
 				     addr, state->sp);
 }
@@ -25,11 +27,12 @@ bool unwind_next_frame(struct unwind_sta
 		return false;
 
 	do {
-		unsigned long addr = READ_ONCE_NOCHECK(*state->sp);
+		for (state->sp++; state->sp < info->end; state->sp++) {
+			unsigned long addr = READ_ONCE_NOCHECK(*state->sp);
 
-		for (state->sp++; state->sp < info->end; state->sp++)
 			if (__kernel_text_address(addr))
 				return true;
+		}
 
 		state->sp = info->next_sp;
 
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/x86/platform/olpc/olpc-xo15-sci.c linux-libre-4.9-gnu/arch/x86/platform/olpc/olpc-xo15-sci.c
--- linux-libre-4.9-rc8-gnu/arch/x86/platform/olpc/olpc-xo15-sci.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/x86/platform/olpc/olpc-xo15-sci.c	2016-12-11 14:17:54.000000000 -0500
@@ -196,6 +196,7 @@ static int xo15_sci_remove(struct acpi_d
 	return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
 static int xo15_sci_resume(struct device *dev)
 {
 	/* Enable all EC events */
@@ -207,6 +208,7 @@ static int xo15_sci_resume(struct device
 
 	return 0;
 }
+#endif
 
 static SIMPLE_DEV_PM_OPS(xo15_sci_pm, NULL, xo15_sci_resume);
 
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/arch/x86/tools/relocs.h linux-libre-4.9-gnu/arch/x86/tools/relocs.h
--- linux-libre-4.9-rc8-gnu/arch/x86/tools/relocs.h	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/arch/x86/tools/relocs.h	2016-12-11 14:17:54.000000000 -0500
@@ -16,7 +16,7 @@
 #include <regex.h>
 #include <tools/le_byteshift.h>
 
-void die(char *fmt, ...);
+void die(char *fmt, ...) __attribute__((noreturn));
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
 
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/block/blk-map.c linux-libre-4.9-gnu/block/blk-map.c
--- linux-libre-4.9-rc8-gnu/block/blk-map.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/block/blk-map.c	2016-12-11 14:17:54.000000000 -0500
@@ -118,6 +118,9 @@ int blk_rq_map_user_iov(struct request_q
 	struct iov_iter i;
 	int ret;
 
+	if (!iter_is_iovec(iter))
+		goto fail;
+
 	if (map_data)
 		copy = true;
 	else if (iov_iter_alignment(iter) & align)
@@ -140,6 +143,7 @@ int blk_rq_map_user_iov(struct request_q
 
 unmap_rq:
 	__blk_rq_unmap_user(bio);
+fail:
 	rq->bio = NULL;
 	return -EINVAL;
 }
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/crypto/algif_aead.c linux-libre-4.9-gnu/crypto/algif_aead.c
--- linux-libre-4.9-rc8-gnu/crypto/algif_aead.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/crypto/algif_aead.c	2016-12-11 14:17:54.000000000 -0500
@@ -81,7 +81,11 @@ static inline bool aead_sufficient_data(
 {
 	unsigned as = crypto_aead_authsize(crypto_aead_reqtfm(&ctx->aead_req));
 
-	return ctx->used >= ctx->aead_assoclen + as;
+	/*
+	 * The minimum amount of memory needed for an AEAD cipher is
+	 * the AAD and in case of decryption the tag.
+	 */
+	return ctx->used >= ctx->aead_assoclen + (ctx->enc ? 0 : as);
 }
 
 static void aead_reset_ctx(struct aead_ctx *ctx)
@@ -416,7 +420,7 @@ static int aead_recvmsg_async(struct soc
 	unsigned int i, reqlen = GET_REQ_SIZE(tfm);
 	int err = -ENOMEM;
 	unsigned long used;
-	size_t outlen;
+	size_t outlen = 0;
 	size_t usedpages = 0;
 
 	lock_sock(sk);
@@ -426,12 +430,15 @@ static int aead_recvmsg_async(struct soc
 			goto unlock;
 	}
 
-	used = ctx->used;
-	outlen = used;
-
 	if (!aead_sufficient_data(ctx))
 		goto unlock;
 
+	used = ctx->used;
+	if (ctx->enc)
+		outlen = used + as;
+	else
+		outlen = used - as;
+
 	req = sock_kmalloc(sk, reqlen, GFP_KERNEL);
 	if (unlikely(!req))
 		goto unlock;
@@ -445,7 +452,7 @@ static int aead_recvmsg_async(struct soc
 	aead_request_set_ad(req, ctx->aead_assoclen);
 	aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
 				  aead_async_cb, sk);
-	used -= ctx->aead_assoclen + (ctx->enc ? as : 0);
+	used -= ctx->aead_assoclen;
 
 	/* take over all tx sgls from ctx */
 	areq->tsgl = sock_kmalloc(sk, sizeof(*areq->tsgl) * sgl->cur,
@@ -461,7 +468,7 @@ static int aead_recvmsg_async(struct soc
 	areq->tsgls = sgl->cur;
 
 	/* create rx sgls */
-	while (iov_iter_count(&msg->msg_iter)) {
+	while (outlen > usedpages && iov_iter_count(&msg->msg_iter)) {
 		size_t seglen = min_t(size_t, iov_iter_count(&msg->msg_iter),
 				      (outlen - usedpages));
 
@@ -491,16 +498,14 @@ static int aead_recvmsg_async(struct soc
 
 		last_rsgl = rsgl;
 
-		/* we do not need more iovecs as we have sufficient memory */
-		if (outlen <= usedpages)
-			break;
-
 		iov_iter_advance(&msg->msg_iter, err);
 	}
-	err = -EINVAL;
+
 	/* ensure output buffer is sufficiently large */
-	if (usedpages < outlen)
-		goto free;
+	if (usedpages < outlen) {
+		err = -EINVAL;
+		goto unlock;
+	}
 
 	aead_request_set_crypt(req, areq->tsgl, areq->first_rsgl.sgl.sg, used,
 			       areq->iv);
@@ -571,6 +576,7 @@ static int aead_recvmsg_sync(struct sock
 			goto unlock;
 	}
 
+	/* data length provided by caller via sendmsg/sendpage */
 	used = ctx->used;
 
 	/*
@@ -585,16 +591,27 @@ static int aead_recvmsg_sync(struct sock
 	if (!aead_sufficient_data(ctx))
 		goto unlock;
 
-	outlen = used;
+	/*
+	 * Calculate the minimum output buffer size holding the result of the
+	 * cipher operation. When encrypting data, the receiving buffer is
+	 * larger by the tag length compared to the input buffer as the
+	 * encryption operation generates the tag. For decryption, the input
+	 * buffer provides the tag which is consumed resulting in only the
+	 * plaintext without a buffer for the tag returned to the caller.
+	 */
+	if (ctx->enc)
+		outlen = used + as;
+	else
+		outlen = used - as;
 
 	/*
 	 * The cipher operation input data is reduced by the associated data
 	 * length as this data is processed separately later on.
 	 */
-	used -= ctx->aead_assoclen + (ctx->enc ? as : 0);
+	used -= ctx->aead_assoclen;
 
 	/* convert iovecs of output buffers into scatterlists */
-	while (iov_iter_count(&msg->msg_iter)) {
+	while (outlen > usedpages && iov_iter_count(&msg->msg_iter)) {
 		size_t seglen = min_t(size_t, iov_iter_count(&msg->msg_iter),
 				      (outlen - usedpages));
 
@@ -621,16 +638,14 @@ static int aead_recvmsg_sync(struct sock
 
 		last_rsgl = rsgl;
 
-		/* we do not need more iovecs as we have sufficient memory */
-		if (outlen <= usedpages)
-			break;
 		iov_iter_advance(&msg->msg_iter, err);
 	}
 
-	err = -EINVAL;
 	/* ensure output buffer is sufficiently large */
-	if (usedpages < outlen)
+	if (usedpages < outlen) {
+		err = -EINVAL;
 		goto unlock;
+	}
 
 	sg_mark_end(sgl->sg + sgl->cur - 1);
 	aead_request_set_crypt(&ctx->aead_req, sgl->sg, ctx->first_rsgl.sgl.sg,
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/crypto/drbg.c linux-libre-4.9-gnu/crypto/drbg.c
--- linux-libre-4.9-rc8-gnu/crypto/drbg.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/crypto/drbg.c	2016-12-11 14:17:54.000000000 -0500
@@ -262,6 +262,7 @@ static int drbg_kcapi_sym_ctr(struct drb
 			      u8 *inbuf, u32 inbuflen,
 			      u8 *outbuf, u32 outlen);
 #define DRBG_CTR_NULL_LEN 128
+#define DRBG_OUTSCRATCHLEN DRBG_CTR_NULL_LEN
 
 /* BCC function for CTR DRBG as defined in 10.4.3 */
 static int drbg_ctr_bcc(struct drbg_state *drbg,
@@ -1644,6 +1645,9 @@ static int drbg_fini_sym_kernel(struct d
 	kfree(drbg->ctr_null_value_buf);
 	drbg->ctr_null_value = NULL;
 
+	kfree(drbg->outscratchpadbuf);
+	drbg->outscratchpadbuf = NULL;
+
 	return 0;
 }
 
@@ -1708,6 +1712,15 @@ static int drbg_init_sym_kernel(struct d
 	drbg->ctr_null_value = (u8 *)PTR_ALIGN(drbg->ctr_null_value_buf,
 					       alignmask + 1);
 
+	drbg->outscratchpadbuf = kmalloc(DRBG_OUTSCRATCHLEN + alignmask,
+					 GFP_KERNEL);
+	if (!drbg->outscratchpadbuf) {
+		drbg_fini_sym_kernel(drbg);
+		return -ENOMEM;
+	}
+	drbg->outscratchpad = (u8 *)PTR_ALIGN(drbg->outscratchpadbuf,
+					      alignmask + 1);
+
 	return alignmask;
 }
 
@@ -1737,15 +1750,16 @@ static int drbg_kcapi_sym_ctr(struct drb
 			      u8 *outbuf, u32 outlen)
 {
 	struct scatterlist sg_in;
+	int ret;
 
 	sg_init_one(&sg_in, inbuf, inlen);
 
 	while (outlen) {
-		u32 cryptlen = min_t(u32, inlen, outlen);
+		u32 cryptlen = min3(inlen, outlen, (u32)DRBG_OUTSCRATCHLEN);
 		struct scatterlist sg_out;
-		int ret;
 
-		sg_init_one(&sg_out, outbuf, cryptlen);
+		/* Output buffer may not be valid for SGL, use scratchpad */
+		sg_init_one(&sg_out, drbg->outscratchpad, cryptlen);
 		skcipher_request_set_crypt(drbg->ctr_req, &sg_in, &sg_out,
 					   cryptlen, drbg->V);
 		ret = crypto_skcipher_encrypt(drbg->ctr_req);
@@ -1761,14 +1775,19 @@ static int drbg_kcapi_sym_ctr(struct drb
 				break;
 			}
 		default:
-			return ret;
+			goto out;
 		}
 		init_completion(&drbg->ctr_completion);
 
+		memcpy(outbuf, drbg->outscratchpad, cryptlen);
+
 		outlen -= cryptlen;
 	}
+	ret = 0;
 
-	return 0;
+out:
+	memzero_explicit(drbg->outscratchpad, DRBG_OUTSCRATCHLEN);
+	return ret;
 }
 #endif /* CONFIG_CRYPTO_DRBG_CTR */
 
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/crypto/Makefile linux-libre-4.9-gnu/crypto/Makefile
--- linux-libre-4.9-rc8-gnu/crypto/Makefile	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/crypto/Makefile	2016-12-11 14:17:54.000000000 -0500
@@ -40,6 +40,7 @@ obj-$(CONFIG_CRYPTO_ECDH) += ecdh_generi
 
 $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
 $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
+$(obj)/rsa_helper.o: $(obj)/rsapubkey-asn1.h $(obj)/rsaprivkey-asn1.h
 clean-files += rsapubkey-asn1.c rsapubkey-asn1.h
 clean-files += rsaprivkey-asn1.c rsaprivkey-asn1.h
 
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/crypto/mcryptd.c linux-libre-4.9-gnu/crypto/mcryptd.c
--- linux-libre-4.9-rc8-gnu/crypto/mcryptd.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/crypto/mcryptd.c	2016-12-11 14:17:54.000000000 -0500
@@ -254,18 +254,22 @@ out_free_inst:
 	goto out;
 }
 
-static inline void mcryptd_check_internal(struct rtattr **tb, u32 *type,
+static inline bool mcryptd_check_internal(struct rtattr **tb, u32 *type,
 					  u32 *mask)
 {
 	struct crypto_attr_type *algt;
 
 	algt = crypto_get_attr_type(tb);
 	if (IS_ERR(algt))
-		return;
-	if ((algt->type & CRYPTO_ALG_INTERNAL))
-		*type |= CRYPTO_ALG_INTERNAL;
-	if ((algt->mask & CRYPTO_ALG_INTERNAL))
-		*mask |= CRYPTO_ALG_INTERNAL;
+		return false;
+
+	*type |= algt->type & CRYPTO_ALG_INTERNAL;
+	*mask |= algt->mask & CRYPTO_ALG_INTERNAL;
+
+	if (*type & *mask & CRYPTO_ALG_INTERNAL)
+		return true;
+	else
+		return false;
 }
 
 static int mcryptd_hash_init_tfm(struct crypto_tfm *tfm)
@@ -492,7 +496,8 @@ static int mcryptd_create_hash(struct cr
 	u32 mask = 0;
 	int err;
 
-	mcryptd_check_internal(tb, &type, &mask);
+	if (!mcryptd_check_internal(tb, &type, &mask))
+		return -EINVAL;
 
 	halg = ahash_attr_alg(tb[1], type, mask);
 	if (IS_ERR(halg))
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/acpi/nfit/core.c linux-libre-4.9-gnu/drivers/acpi/nfit/core.c
--- linux-libre-4.9-rc8-gnu/drivers/acpi/nfit/core.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/acpi/nfit/core.c	2016-12-11 14:17:54.000000000 -0500
@@ -94,7 +94,7 @@ static struct acpi_device *to_acpi_dev(s
 	return to_acpi_device(acpi_desc->dev);
 }
 
-static int xlat_status(void *buf, unsigned int cmd, u32 status)
+static int xlat_bus_status(void *buf, unsigned int cmd, u32 status)
 {
 	struct nd_cmd_clear_error *clear_err;
 	struct nd_cmd_ars_status *ars_status;
@@ -113,7 +113,7 @@ static int xlat_status(void *buf, unsign
 		flags = ND_ARS_PERSISTENT | ND_ARS_VOLATILE;
 		if ((status >> 16 & flags) == 0)
 			return -ENOTTY;
-		break;
+		return 0;
 	case ND_CMD_ARS_START:
 		/* ARS is in progress */
 		if ((status & 0xffff) == NFIT_ARS_START_BUSY)
@@ -122,7 +122,7 @@ static int xlat_status(void *buf, unsign
 		/* Command failed */
 		if (status & 0xffff)
 			return -EIO;
-		break;
+		return 0;
 	case ND_CMD_ARS_STATUS:
 		ars_status = buf;
 		/* Command failed */
@@ -146,7 +146,8 @@ static int xlat_status(void *buf, unsign
 		 * then just continue with the returned results.
 		 */
 		if (status == NFIT_ARS_STATUS_INTR) {
-			if (ars_status->flags & NFIT_ARS_F_OVERFLOW)
+			if (ars_status->out_length >= 40 && (ars_status->flags
+						& NFIT_ARS_F_OVERFLOW))
 				return -ENOSPC;
 			return 0;
 		}
@@ -154,7 +155,7 @@ static int xlat_status(void *buf, unsign
 		/* Unknown status */
 		if (status >> 16)
 			return -EIO;
-		break;
+		return 0;
 	case ND_CMD_CLEAR_ERROR:
 		clear_err = buf;
 		if (status & 0xffff)
@@ -163,7 +164,7 @@ static int xlat_status(void *buf, unsign
 			return -EIO;
 		if (clear_err->length > clear_err->cleared)
 			return clear_err->cleared;
-		break;
+		return 0;
 	default:
 		break;
 	}
@@ -174,9 +175,18 @@ static int xlat_status(void *buf, unsign
 	return 0;
 }
 
-static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
-		struct nvdimm *nvdimm, unsigned int cmd, void *buf,
-		unsigned int buf_len, int *cmd_rc)
+static int xlat_status(struct nvdimm *nvdimm, void *buf, unsigned int cmd,
+		u32 status)
+{
+	if (!nvdimm)
+		return xlat_bus_status(buf, cmd, status);
+	if (status)
+		return -EIO;
+	return 0;
+}
+
+int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm,
+		unsigned int cmd, void *buf, unsigned int buf_len, int *cmd_rc)
 {
 	struct acpi_nfit_desc *acpi_desc = to_acpi_nfit_desc(nd_desc);
 	union acpi_object in_obj, in_buf, *out_obj;
@@ -298,7 +308,8 @@ static int acpi_nfit_ctl(struct nvdimm_b
 
 	for (i = 0, offset = 0; i < desc->out_num; i++) {
 		u32 out_size = nd_cmd_out_size(nvdimm, cmd, desc, i, buf,
-				(u32 *) out_obj->buffer.pointer);
+				(u32 *) out_obj->buffer.pointer,
+				out_obj->buffer.length - offset);
 
 		if (offset + out_size > out_obj->buffer.length) {
 			dev_dbg(dev, "%s:%s output object underflow cmd: %s field: %d\n",
@@ -333,7 +344,8 @@ static int acpi_nfit_ctl(struct nvdimm_b
 			 */
 			rc = buf_len - offset - in_buf.buffer.length;
 			if (cmd_rc)
-				*cmd_rc = xlat_status(buf, cmd, fw_status);
+				*cmd_rc = xlat_status(nvdimm, buf, cmd,
+						fw_status);
 		} else {
 			dev_err(dev, "%s:%s underrun cmd: %s buf_len: %d out_len: %d\n",
 					__func__, dimm_name, cmd_name, buf_len,
@@ -343,7 +355,7 @@ static int acpi_nfit_ctl(struct nvdimm_b
 	} else {
 		rc = 0;
 		if (cmd_rc)
-			*cmd_rc = xlat_status(buf, cmd, fw_status);
+			*cmd_rc = xlat_status(nvdimm, buf, cmd, fw_status);
 	}
 
  out:
@@ -351,6 +363,7 @@ static int acpi_nfit_ctl(struct nvdimm_b
 
 	return rc;
 }
+EXPORT_SYMBOL_GPL(acpi_nfit_ctl);
 
 static const char *spa_type_name(u16 type)
 {
@@ -2001,19 +2014,32 @@ static int ars_get_status(struct acpi_nf
 	return cmd_rc;
 }
 
-static int ars_status_process_records(struct nvdimm_bus *nvdimm_bus,
+static int ars_status_process_records(struct acpi_nfit_desc *acpi_desc,
 		struct nd_cmd_ars_status *ars_status)
 {
+	struct nvdimm_bus *nvdimm_bus = acpi_desc->nvdimm_bus;
 	int rc;
 	u32 i;
 
+	/*
+	 * First record starts at 44 byte offset from the start of the
+	 * payload.
+	 */
+	if (ars_status->out_length < 44)
+		return 0;
 	for (i = 0; i < ars_status->num_records; i++) {
+		/* only process full records */
+		if (ars_status->out_length
+				< 44 + sizeof(struct nd_ars_record) * (i + 1))
+			break;
 		rc = nvdimm_bus_add_poison(nvdimm_bus,
 				ars_status->records[i].err_address,
 				ars_status->records[i].length);
 		if (rc)
 			return rc;
 	}
+	if (i < ars_status->num_records)
+		dev_warn(acpi_desc->dev, "detected truncated ars results\n");
 
 	return 0;
 }
@@ -2266,8 +2292,7 @@ static int acpi_nfit_query_poison(struct
 	if (rc < 0 && rc != -ENOSPC)
 		return rc;
 
-	if (ars_status_process_records(acpi_desc->nvdimm_bus,
-				acpi_desc->ars_status))
+	if (ars_status_process_records(acpi_desc, acpi_desc->ars_status))
 		return -ENOMEM;
 
 	return 0;
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/acpi/nfit/nfit.h linux-libre-4.9-gnu/drivers/acpi/nfit/nfit.h
--- linux-libre-4.9-rc8-gnu/drivers/acpi/nfit/nfit.h	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/acpi/nfit/nfit.h	2016-12-11 14:17:54.000000000 -0500
@@ -240,5 +240,7 @@ const u8 *to_nfit_uuid(enum nfit_uuids i
 int acpi_nfit_init(struct acpi_nfit_desc *acpi_desc, void *nfit, acpi_size sz);
 void __acpi_nfit_notify(struct device *dev, acpi_handle handle, u32 event);
 void __acpi_nvdimm_notify(struct device *dev, u32 event);
+int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm,
+		unsigned int cmd, void *buf, unsigned int buf_len, int *cmd_rc);
 void acpi_nfit_desc_init(struct acpi_nfit_desc *acpi_desc, struct device *dev);
 #endif /* __NFIT_H__ */
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/ata/libata-scsi.c linux-libre-4.9-gnu/drivers/ata/libata-scsi.c
--- linux-libre-4.9-rc8-gnu/drivers/ata/libata-scsi.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/ata/libata-scsi.c	2016-12-11 14:17:54.000000000 -0500
@@ -1159,6 +1159,7 @@ static void ata_scsi_sdev_config(struct
 {
 	sdev->use_10_for_rw = 1;
 	sdev->use_10_for_ms = 1;
+	sdev->no_write_same = 1;
 
 	/* Schedule policy is determined by ->qc_defer() callback and
 	 * it needs to see every deferred qc.  Set dev_blocked to 1 to
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/ata/sata_mv.c linux-libre-4.9-gnu/drivers/ata/sata_mv.c
--- linux-libre-4.9-rc8-gnu/drivers/ata/sata_mv.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/ata/sata_mv.c	2016-12-11 14:17:54.000000000 -0500
@@ -4090,7 +4090,20 @@ static int mv_platform_probe(struct plat
 
 	/* allocate host */
 	if (pdev->dev.of_node) {
-		of_property_read_u32(pdev->dev.of_node, "nr-ports", &n_ports);
+		rc = of_property_read_u32(pdev->dev.of_node, "nr-ports",
+					   &n_ports);
+		if (rc) {
+			dev_err(&pdev->dev,
+				"error parsing nr-ports property: %d\n", rc);
+			return rc;
+		}
+
+		if (n_ports <= 0) {
+			dev_err(&pdev->dev, "nr-ports must be positive: %d\n",
+				n_ports);
+			return -EINVAL;
+		}
+
 		irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
 	} else {
 		mv_platform_data = dev_get_platdata(&pdev->dev);
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/atm/eni.c linux-libre-4.9-gnu/drivers/atm/eni.c
--- linux-libre-4.9-rc8-gnu/drivers/atm/eni.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/atm/eni.c	2016-12-11 14:17:54.000000000 -0500
@@ -1727,7 +1727,7 @@ static int eni_do_init(struct atm_dev *d
 		printk("\n");
 		printk(KERN_ERR DEV_LABEL "(itf %d): can't set up page "
 		    "mapping\n",dev->number);
-		return error;
+		return -ENOMEM;
 	}
 	eni_dev->ioaddr = base;
 	eni_dev->base_diff = real_base - (unsigned long) base;
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/atm/lanai.c linux-libre-4.9-gnu/drivers/atm/lanai.c
--- linux-libre-4.9-rc8-gnu/drivers/atm/lanai.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/atm/lanai.c	2016-12-11 14:17:54.000000000 -0500
@@ -2143,6 +2143,7 @@ static int lanai_dev_open(struct atm_dev
 	lanai->base = (bus_addr_t) ioremap(raw_base, LANAI_MAPPING_SIZE);
 	if (lanai->base == NULL) {
 		printk(KERN_ERR DEV_LABEL ": couldn't remap I/O space\n");
+		result = -ENOMEM;
 		goto error_pci;
 	}
 	/* 3.3: Reset lanai and PHY */
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/block/zram/zram_drv.c linux-libre-4.9-gnu/drivers/block/zram/zram_drv.c
--- linux-libre-4.9-rc8-gnu/drivers/block/zram/zram_drv.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/block/zram/zram_drv.c	2016-12-11 14:17:54.000000000 -0500
@@ -1413,8 +1413,14 @@ static ssize_t hot_remove_store(struct c
 	return ret ? ret : count;
 }
 
+/*
+ * NOTE: hot_add attribute is not the usual read-only sysfs attribute. In a
+ * sense that reading from this file does alter the state of your system -- it
+ * creates a new un-initialized zram device and returns back this device's
+ * device_id (or an error code if it fails to create a new device).
+ */
 static struct class_attribute zram_control_class_attrs[] = {
-	__ATTR_RO(hot_add),
+	__ATTR(hot_add, 0400, hot_add_show, NULL),
 	__ATTR_WO(hot_remove),
 	__ATTR_NULL,
 };
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/crypto/caam/ctrl.c linux-libre-4.9-gnu/drivers/crypto/caam/ctrl.c
--- linux-libre-4.9-rc8-gnu/drivers/crypto/caam/ctrl.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/crypto/caam/ctrl.c	2016-12-11 14:17:54.000000000 -0500
@@ -558,8 +558,9 @@ static int caam_probe(struct platform_de
 	 * Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel,
 	 * long pointers in master configuration register
 	 */
-	clrsetbits_32(&ctrl->mcr, MCFGR_AWCACHE_MASK, MCFGR_AWCACHE_CACH |
-		      MCFGR_AWCACHE_BUFF | MCFGR_WDENABLE | MCFGR_LARGE_BURST |
+	clrsetbits_32(&ctrl->mcr, MCFGR_AWCACHE_MASK | MCFGR_LONG_PTR,
+		      MCFGR_AWCACHE_CACH | MCFGR_AWCACHE_BUFF |
+		      MCFGR_WDENABLE | MCFGR_LARGE_BURST |
 		      (sizeof(dma_addr_t) == sizeof(u64) ? MCFGR_LONG_PTR : 0));
 
 	/*
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/crypto/chelsio/chcr_algo.h linux-libre-4.9-gnu/drivers/crypto/chelsio/chcr_algo.h
--- linux-libre-4.9-rc8-gnu/drivers/crypto/chelsio/chcr_algo.h	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/crypto/chelsio/chcr_algo.h	2016-12-11 14:17:54.000000000 -0500
@@ -422,7 +422,7 @@ static inline void get_aes_decrypt_key(u
 {
 	u32 temp;
 	u32 w_ring[MAX_NK];
-	int i, j, k = 0;
+	int i, j, k;
 	u8  nr, nk;
 
 	switch (keylength) {
@@ -460,6 +460,7 @@ static inline void get_aes_decrypt_key(u
 		temp = w_ring[i % nk];
 		i++;
 	}
+	i--;
 	for (k = 0, j = i % nk; k < nk; k++) {
 		*((u32 *)dec_key + k) = htonl(w_ring[j]);
 		j--;
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/crypto/marvell/hash.c linux-libre-4.9-gnu/drivers/crypto/marvell/hash.c
--- linux-libre-4.9-rc8-gnu/drivers/crypto/marvell/hash.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/crypto/marvell/hash.c	2016-12-11 14:17:54.000000000 -0500
@@ -168,12 +168,11 @@ static void mv_cesa_ahash_std_step(struc
 	mv_cesa_adjust_op(engine, &creq->op_tmpl);
 	memcpy_toio(engine->sram, &creq->op_tmpl, sizeof(creq->op_tmpl));
 
-	digsize = crypto_ahash_digestsize(crypto_ahash_reqtfm(req));
-	for (i = 0; i < digsize / 4; i++)
-		writel_relaxed(creq->state[i], engine->regs + CESA_IVDIG(i));
-
-	mv_cesa_adjust_op(engine, &creq->op_tmpl);
-	memcpy_toio(engine->sram, &creq->op_tmpl, sizeof(creq->op_tmpl));
+	if (!sreq->offset) {
+		digsize = crypto_ahash_digestsize(crypto_ahash_reqtfm(req));
+		for (i = 0; i < digsize / 4; i++)
+			writel_relaxed(creq->state[i], engine->regs + CESA_IVDIG(i));
+	}
 
 	if (creq->cache_ptr)
 		memcpy_toio(engine->sram + CESA_SA_DATA_SRAM_OFFSET,
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/dax/dax.c linux-libre-4.9-gnu/drivers/dax/dax.c
--- linux-libre-4.9-rc8-gnu/drivers/dax/dax.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/dax/dax.c	2016-12-11 14:17:54.000000000 -0500
@@ -271,7 +271,7 @@ static int check_vma(struct dax_dev *dax
 		return -ENXIO;
 
 	/* prevent private mappings from being established */
-	if ((vma->vm_flags & VM_SHARED) != VM_SHARED) {
+	if ((vma->vm_flags & VM_MAYSHARE) != VM_MAYSHARE) {
 		dev_info(dev, "%s: %s: fail, attempted private mapping\n",
 				current->comm, func);
 		return -EINVAL;
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c linux-libre-4.9-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
--- linux-libre-4.9-rc8-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c	2016-12-04 17:37:20.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c	2016-12-11 17:41:21.000000000 -0500
@@ -1493,7 +1493,7 @@ static int amdgpu_fini(struct amdgpu_dev
 	return 0;
 }
 
-static int amdgpu_suspend(struct amdgpu_device *adev)
+int amdgpu_suspend(struct amdgpu_device *adev)
 {
 	int i, r;
 
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c linux-libre-4.9-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
--- linux-libre-4.9-rc8-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c	2016-12-11 14:17:54.000000000 -0500
@@ -479,12 +479,15 @@ amdgpu_pci_remove(struct pci_dev *pdev)
 static void
 amdgpu_pci_shutdown(struct pci_dev *pdev)
 {
+	struct drm_device *dev = pci_get_drvdata(pdev);
+	struct amdgpu_device *adev = dev->dev_private;
+
 	/* if we are running in a VM, make sure the device
 	 * torn down properly on reboot/shutdown.
 	 * unfortunately we can't detect certain
 	 * hypervisors so just do this all the time.
 	 */
-	amdgpu_pci_remove(pdev);
+	amdgpu_suspend(adev);
 }
 
 static int amdgpu_pmops_suspend(struct device *dev)
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu.h linux-libre-4.9-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu.h
--- linux-libre-4.9-rc8-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu.h	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/gpu/drm/amd/amdgpu/amdgpu.h	2016-12-11 14:17:54.000000000 -0500
@@ -2472,6 +2472,7 @@ void amdgpu_driver_postclose_kms(struct
 				 struct drm_file *file_priv);
 void amdgpu_driver_preclose_kms(struct drm_device *dev,
 				struct drm_file *file_priv);
+int amdgpu_suspend(struct amdgpu_device *adev);
 int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon);
 int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon);
 u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe);
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/isdn/gigaset/ser-gigaset.c linux-libre-4.9-gnu/drivers/isdn/gigaset/ser-gigaset.c
--- linux-libre-4.9-rc8-gnu/drivers/isdn/gigaset/ser-gigaset.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/isdn/gigaset/ser-gigaset.c	2016-12-11 14:17:54.000000000 -0500
@@ -755,8 +755,10 @@ static int __init ser_gigaset_init(void)
 	driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS,
 				    GIGASET_MODULENAME, GIGASET_DEVNAME,
 				    &ops, THIS_MODULE);
-	if (!driver)
+	if (!driver) {
+		rc = -ENOMEM;
 		goto error;
+	}
 
 	rc = tty_register_ldisc(N_GIGASET_M101, &gigaset_ldisc);
 	if (rc != 0) {
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/isdn/hisax/hfc4s8s_l1.c linux-libre-4.9-gnu/drivers/isdn/hisax/hfc4s8s_l1.c
--- linux-libre-4.9-rc8-gnu/drivers/isdn/hisax/hfc4s8s_l1.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/isdn/hisax/hfc4s8s_l1.c	2016-12-11 14:17:54.000000000 -0500
@@ -1499,6 +1499,7 @@ hfc4s8s_probe(struct pci_dev *pdev, cons
 		printk(KERN_INFO
 		       "HFC-4S/8S: failed to request address space at 0x%04x\n",
 		       hw->iobase);
+		err = -EBUSY;
 		goto out;
 	}
 
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/can/usb/peak_usb/pcan_usb_core.c linux-libre-4.9-gnu/drivers/net/can/usb/peak_usb/pcan_usb_core.c
--- linux-libre-4.9-rc8-gnu/drivers/net/can/usb/peak_usb/pcan_usb_core.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/can/usb/peak_usb/pcan_usb_core.c	2016-12-11 14:17:54.000000000 -0500
@@ -870,23 +870,25 @@ lbl_free_candev:
 static void peak_usb_disconnect(struct usb_interface *intf)
 {
 	struct peak_usb_device *dev;
+	struct peak_usb_device *dev_prev_siblings;
 
 	/* unregister as many netdev devices as siblings */
-	for (dev = usb_get_intfdata(intf); dev; dev = dev->prev_siblings) {
+	for (dev = usb_get_intfdata(intf); dev; dev = dev_prev_siblings) {
 		struct net_device *netdev = dev->netdev;
 		char name[IFNAMSIZ];
 
+		dev_prev_siblings = dev->prev_siblings;
 		dev->state &= ~PCAN_USB_STATE_CONNECTED;
 		strncpy(name, netdev->name, IFNAMSIZ);
 
 		unregister_netdev(netdev);
-		free_candev(netdev);
 
 		kfree(dev->cmd_buf);
 		dev->next_siblings = NULL;
 		if (dev->adapter->dev_free)
 			dev->adapter->dev_free(dev);
 
+		free_candev(netdev);
 		dev_info(&intf->dev, "%s removed\n", name);
 	}
 
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c linux-libre-4.9-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
--- linux-libre-4.9-rc8-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c	2016-12-11 14:17:54.000000000 -0500
@@ -1872,8 +1872,16 @@ static void bnx2x_get_ringparam(struct n
 
 	ering->rx_max_pending = MAX_RX_AVAIL;
 
+	/* If size isn't already set, we give an estimation of the number
+	 * of buffers we'll have. We're neglecting some possible conditions
+	 * [we couldn't know for certain at this point if number of queues
+	 * might shrink] but the number would be correct for the likely
+	 * scenario.
+	 */
 	if (bp->rx_ring_size)
 		ering->rx_pending = bp->rx_ring_size;
+	else if (BNX2X_NUM_RX_QUEUES(bp))
+		ering->rx_pending = MAX_RX_AVAIL / BNX2X_NUM_RX_QUEUES(bp);
 	else
 		ering->rx_pending = MAX_RX_AVAIL;
 
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c linux-libre-4.9-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
--- linux-libre-4.9-rc8-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c	2016-12-04 17:48:42.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c	2016-12-11 17:49:18.000000000 -0500
@@ -10132,7 +10132,7 @@ static void __bnx2x_add_udp_port(struct
 {
 	struct bnx2x_udp_tunnel *udp_port = &bp->udp_tunnel_ports[type];
 
-	if (!netif_running(bp->dev) || !IS_PF(bp))
+	if (!netif_running(bp->dev) || !IS_PF(bp) || CHIP_IS_E1x(bp))
 		return;
 
 	if (udp_port->count && udp_port->dst_port == port) {
@@ -10157,7 +10157,7 @@ static void __bnx2x_del_udp_port(struct
 {
 	struct bnx2x_udp_tunnel *udp_port = &bp->udp_tunnel_ports[type];
 
-	if (!IS_PF(bp))
+	if (!IS_PF(bp) || CHIP_IS_E1x(bp))
 		return;
 
 	if (!udp_port->count || udp_port->dst_port != port) {
@@ -13441,6 +13441,7 @@ static int bnx2x_init_firmware(struct bn
 
 	/* Initialize the pointers to the init arrays */
 	/* Blob */
+	rc = -ENOMEM;
 	BNX2X_ALLOC_AND_SET(init_data, request_firmware_exit, be32_to_cpu_n);
 
 	/* Opcodes */
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/ethernet/broadcom/bnxt/bnxt.c linux-libre-4.9-gnu/drivers/net/ethernet/broadcom/bnxt/bnxt.c
--- linux-libre-4.9-rc8-gnu/drivers/net/ethernet/broadcom/bnxt/bnxt.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/ethernet/broadcom/bnxt/bnxt.c	2016-12-11 14:17:54.000000000 -0500
@@ -4120,7 +4120,7 @@ static int bnxt_hwrm_stat_ctx_alloc(stru
 		bp->grp_info[i].fw_stats_ctx = cpr->hw_stats_ctx_id;
 	}
 	mutex_unlock(&bp->hwrm_cmd_lock);
-	return 0;
+	return rc;
 }
 
 static int bnxt_hwrm_func_qcfg(struct bnxt *bp)
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c linux-libre-4.9-gnu/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
--- linux-libre-4.9-rc8-gnu/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c	2016-12-04 17:49:24.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c	2016-12-11 17:49:40.000000000 -0500
@@ -4929,6 +4929,7 @@ static int init_one(struct pci_dev *pdev
 	 */
 	for_each_port(adapter, i) {
 		pi = adap2pinfo(adapter, i);
+		adapter->port[i]->dev_port = pi->lport;
 		netif_set_real_num_tx_queues(adapter->port[i], pi->nqsets);
 		netif_set_real_num_rx_queues(adapter->port[i], pi->nqsets);
 
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c linux-libre-4.9-gnu/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
--- linux-libre-4.9-rc8-gnu/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c	2016-12-11 14:17:54.000000000 -0500
@@ -7851,7 +7851,6 @@ int t4_port_init(struct adapter *adap, i
 			return ret;
 
 		memcpy(adap->port[i]->dev_addr, addr, ETH_ALEN);
-		adap->port[i]->dev_port = j;
 		j++;
 	}
 	return 0;
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c linux-libre-4.9-gnu/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
--- linux-libre-4.9-rc8-gnu/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c	2016-12-11 14:17:54.000000000 -0500
@@ -2969,6 +2969,7 @@ static int cxgb4vf_pci_probe(struct pci_
 
 		netdev->netdev_ops = &cxgb4vf_netdev_ops;
 		netdev->ethtool_ops = &cxgb4vf_ethtool_ops;
+		netdev->dev_port = pi->port_id;
 
 		/*
 		 * Initialize the hardware/software state for the port.
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/ethernet/cirrus/ep93xx_eth.c linux-libre-4.9-gnu/drivers/net/ethernet/cirrus/ep93xx_eth.c
--- linux-libre-4.9-rc8-gnu/drivers/net/ethernet/cirrus/ep93xx_eth.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/ethernet/cirrus/ep93xx_eth.c	2016-12-11 14:17:54.000000000 -0500
@@ -468,6 +468,9 @@ static void ep93xx_free_buffers(struct e
 	struct device *dev = ep->dev->dev.parent;
 	int i;
 
+	if (!ep->descs)
+		return;
+
 	for (i = 0; i < RX_QUEUE_ENTRIES; i++) {
 		dma_addr_t d;
 
@@ -490,6 +493,7 @@ static void ep93xx_free_buffers(struct e
 
 	dma_free_coherent(dev, sizeof(struct ep93xx_descs), ep->descs,
 							ep->descs_dma_addr);
+	ep->descs = NULL;
 }
 
 static int ep93xx_alloc_buffers(struct ep93xx_priv *ep)
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/ethernet/emulex/benet/be_cmds.c linux-libre-4.9-gnu/drivers/net/ethernet/emulex/benet/be_cmds.c
--- linux-libre-4.9-rc8-gnu/drivers/net/ethernet/emulex/benet/be_cmds.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/ethernet/emulex/benet/be_cmds.c	2016-12-11 14:17:54.000000000 -0500
@@ -90,7 +90,8 @@ static struct be_cmd_priv_map cmd_priv_m
 	{
 		OPCODE_COMMON_SET_HSW_CONFIG,
 		CMD_SUBSYSTEM_COMMON,
-		BE_PRIV_DEVCFG | BE_PRIV_VHADM
+		BE_PRIV_DEVCFG | BE_PRIV_VHADM |
+		BE_PRIV_DEVSEC
 	},
 	{
 		OPCODE_COMMON_GET_EXT_FAT_CAPABILITIES,
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/ethernet/freescale/fec_main.c linux-libre-4.9-gnu/drivers/net/ethernet/freescale/fec_main.c
--- linux-libre-4.9-rc8-gnu/drivers/net/ethernet/freescale/fec_main.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/ethernet/freescale/fec_main.c	2016-12-11 14:17:54.000000000 -0500
@@ -2313,6 +2313,8 @@ static const struct fec_stat {
 	{ "IEEE_rx_octets_ok", IEEE_R_OCTETS_OK },
 };
 
+#define FEC_STATS_SIZE		(ARRAY_SIZE(fec_stats) * sizeof(u64))
+
 static void fec_enet_update_ethtool_stats(struct net_device *dev)
 {
 	struct fec_enet_private *fep = netdev_priv(dev);
@@ -2330,7 +2332,7 @@ static void fec_enet_get_ethtool_stats(s
 	if (netif_running(dev))
 		fec_enet_update_ethtool_stats(dev);
 
-	memcpy(data, fep->ethtool_stats, ARRAY_SIZE(fec_stats) * sizeof(u64));
+	memcpy(data, fep->ethtool_stats, FEC_STATS_SIZE);
 }
 
 static void fec_enet_get_strings(struct net_device *netdev,
@@ -2355,6 +2357,12 @@ static int fec_enet_get_sset_count(struc
 		return -EOPNOTSUPP;
 	}
 }
+
+#else	/* !defined(CONFIG_M5272) */
+#define FEC_STATS_SIZE	0
+static inline void fec_enet_update_ethtool_stats(struct net_device *dev)
+{
+}
 #endif /* !defined(CONFIG_M5272) */
 
 static int fec_enet_nway_reset(struct net_device *dev)
@@ -3293,8 +3301,7 @@ fec_probe(struct platform_device *pdev)
 
 	/* Init network device */
 	ndev = alloc_etherdev_mqs(sizeof(struct fec_enet_private) +
-				  ARRAY_SIZE(fec_stats) * sizeof(u64),
-				  num_tx_qs, num_rx_qs);
+				  FEC_STATS_SIZE, num_tx_qs, num_rx_qs);
 	if (!ndev)
 		return -ENOMEM;
 
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/ethernet/ibm/ibmveth.c linux-libre-4.9-gnu/drivers/net/ethernet/ibm/ibmveth.c
--- linux-libre-4.9-rc8-gnu/drivers/net/ethernet/ibm/ibmveth.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/ethernet/ibm/ibmveth.c	2016-12-11 14:17:54.000000000 -0500
@@ -58,7 +58,7 @@ static struct kobj_type ktype_veth_pool;
 
 static const char ibmveth_driver_name[] = "ibmveth";
 static const char ibmveth_driver_string[] = "IBM Power Virtual Ethernet Driver";
-#define ibmveth_driver_version "1.05"
+#define ibmveth_driver_version "1.06"
 
 MODULE_AUTHOR("Santiago Leon <santil@linux.vnet.ibm.com>");
 MODULE_DESCRIPTION("IBM Power Virtual Ethernet Driver");
@@ -137,6 +137,11 @@ static inline int ibmveth_rxq_frame_offs
 	return ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_OFF_MASK;
 }
 
+static inline int ibmveth_rxq_large_packet(struct ibmveth_adapter *adapter)
+{
+	return ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_LRG_PKT;
+}
+
 static inline int ibmveth_rxq_frame_length(struct ibmveth_adapter *adapter)
 {
 	return be32_to_cpu(adapter->rx_queue.queue_addr[adapter->rx_queue.index].length);
@@ -1174,6 +1179,45 @@ map_failed:
 	goto retry_bounce;
 }
 
+static void ibmveth_rx_mss_helper(struct sk_buff *skb, u16 mss, int lrg_pkt)
+{
+	int offset = 0;
+
+	/* only TCP packets will be aggregated */
+	if (skb->protocol == htons(ETH_P_IP)) {
+		struct iphdr *iph = (struct iphdr *)skb->data;
+
+		if (iph->protocol == IPPROTO_TCP) {
+			offset = iph->ihl * 4;
+			skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
+		} else {
+			return;
+		}
+	} else if (skb->protocol == htons(ETH_P_IPV6)) {
+		struct ipv6hdr *iph6 = (struct ipv6hdr *)skb->data;
+
+		if (iph6->nexthdr == IPPROTO_TCP) {
+			offset = sizeof(struct ipv6hdr);
+			skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
+		} else {
+			return;
+		}
+	} else {
+		return;
+	}
+	/* if mss is not set through Large Packet bit/mss in rx buffer,
+	 * expect that the mss will be written to the tcp header checksum.
+	 */
+	if (lrg_pkt) {
+		skb_shinfo(skb)->gso_size = mss;
+	} else if (offset) {
+		struct tcphdr *tcph = (struct tcphdr *)(skb->data + offset);
+
+		skb_shinfo(skb)->gso_size = ntohs(tcph->check);
+		tcph->check = 0;
+	}
+}
+
 static int ibmveth_poll(struct napi_struct *napi, int budget)
 {
 	struct ibmveth_adapter *adapter =
@@ -1182,6 +1226,7 @@ static int ibmveth_poll(struct napi_stru
 	int frames_processed = 0;
 	unsigned long lpar_rc;
 	struct iphdr *iph;
+	u16 mss = 0;
 
 restart_poll:
 	while (frames_processed < budget) {
@@ -1199,9 +1244,21 @@ restart_poll:
 			int length = ibmveth_rxq_frame_length(adapter);
 			int offset = ibmveth_rxq_frame_offset(adapter);
 			int csum_good = ibmveth_rxq_csum_good(adapter);
+			int lrg_pkt = ibmveth_rxq_large_packet(adapter);
 
 			skb = ibmveth_rxq_get_buffer(adapter);
 
+			/* if the large packet bit is set in the rx queue
+			 * descriptor, the mss will be written by PHYP eight
+			 * bytes from the start of the rx buffer, which is
+			 * skb->data at this stage
+			 */
+			if (lrg_pkt) {
+				__be64 *rxmss = (__be64 *)(skb->data + 8);
+
+				mss = (u16)be64_to_cpu(*rxmss);
+			}
+
 			new_skb = NULL;
 			if (length < rx_copybreak)
 				new_skb = netdev_alloc_skb(netdev, length);
@@ -1235,11 +1292,15 @@ restart_poll:
 					if (iph->check == 0xffff) {
 						iph->check = 0;
 						iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
-						adapter->rx_large_packets++;
 					}
 				}
 			}
 
+			if (length > netdev->mtu + ETH_HLEN) {
+				ibmveth_rx_mss_helper(skb, mss, lrg_pkt);
+				adapter->rx_large_packets++;
+			}
+
 			napi_gro_receive(napi, skb);	/* send it up */
 
 			netdev->stats.rx_packets++;
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/ethernet/ibm/ibmveth.h linux-libre-4.9-gnu/drivers/net/ethernet/ibm/ibmveth.h
--- linux-libre-4.9-rc8-gnu/drivers/net/ethernet/ibm/ibmveth.h	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/ethernet/ibm/ibmveth.h	2016-12-11 14:17:54.000000000 -0500
@@ -209,6 +209,7 @@ struct ibmveth_rx_q_entry {
 #define IBMVETH_RXQ_TOGGLE		0x80000000
 #define IBMVETH_RXQ_TOGGLE_SHIFT	31
 #define IBMVETH_RXQ_VALID		0x40000000
+#define IBMVETH_RXQ_LRG_PKT		0x04000000
 #define IBMVETH_RXQ_NO_CSUM		0x02000000
 #define IBMVETH_RXQ_CSUM_GOOD		0x01000000
 #define IBMVETH_RXQ_OFF_MASK		0x0000FFFF
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/ethernet/lantiq_etop.c linux-libre-4.9-gnu/drivers/net/ethernet/lantiq_etop.c
--- linux-libre-4.9-rc8-gnu/drivers/net/ethernet/lantiq_etop.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/ethernet/lantiq_etop.c	2016-12-11 14:17:54.000000000 -0500
@@ -704,6 +704,7 @@ ltq_etop_probe(struct platform_device *p
 	priv->pldata = dev_get_platdata(&pdev->dev);
 	priv->netdev = dev;
 	spin_lock_init(&priv->lock);
+	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	for (i = 0; i < MAX_DMA_CHAN; i++) {
 		if (IS_TX(i))
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/ethernet/mellanox/mlx5/core/cmd.c linux-libre-4.9-gnu/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
--- linux-libre-4.9-rc8-gnu/drivers/net/ethernet/mellanox/mlx5/core/cmd.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/ethernet/mellanox/mlx5/core/cmd.c	2016-12-11 14:17:54.000000000 -0500
@@ -268,11 +268,6 @@ static void dump_buf(void *buf, int size
 		pr_debug("\n");
 }
 
-enum {
-	MLX5_DRIVER_STATUS_ABORTED = 0xfe,
-	MLX5_DRIVER_SYND = 0xbadd00de,
-};
-
 static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op,
 				       u32 *synd, u8 *status)
 {
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/ethernet/mellanox/mlx5/core/en.h linux-libre-4.9-gnu/drivers/net/ethernet/mellanox/mlx5/core/en.h
--- linux-libre-4.9-rc8-gnu/drivers/net/ethernet/mellanox/mlx5/core/en.h	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/ethernet/mellanox/mlx5/core/en.h	2016-12-11 14:17:54.000000000 -0500
@@ -241,7 +241,7 @@ struct mlx5e_tstamp {
 };
 
 enum {
-	MLX5E_RQ_STATE_FLUSH,
+	MLX5E_RQ_STATE_ENABLED,
 	MLX5E_RQ_STATE_UMR_WQE_IN_PROGRESS,
 	MLX5E_RQ_STATE_AM,
 };
@@ -394,7 +394,7 @@ struct mlx5e_sq_dma {
 };
 
 enum {
-	MLX5E_SQ_STATE_FLUSH,
+	MLX5E_SQ_STATE_ENABLED,
 	MLX5E_SQ_STATE_BF_ENABLE,
 };
 
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_main.c linux-libre-4.9-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
--- linux-libre-4.9-rc8-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_main.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_main.c	2016-12-11 14:17:54.000000000 -0500
@@ -759,6 +759,7 @@ static int mlx5e_open_rq(struct mlx5e_ch
 	if (err)
 		goto err_destroy_rq;
 
+	set_bit(MLX5E_RQ_STATE_ENABLED, &rq->state);
 	err = mlx5e_modify_rq_state(rq, MLX5_RQC_STATE_RST, MLX5_RQC_STATE_RDY);
 	if (err)
 		goto err_disable_rq;
@@ -773,6 +774,7 @@ static int mlx5e_open_rq(struct mlx5e_ch
 	return 0;
 
 err_disable_rq:
+	clear_bit(MLX5E_RQ_STATE_ENABLED, &rq->state);
 	mlx5e_disable_rq(rq);
 err_destroy_rq:
 	mlx5e_destroy_rq(rq);
@@ -782,7 +784,7 @@ err_destroy_rq:
 
 static void mlx5e_close_rq(struct mlx5e_rq *rq)
 {
-	set_bit(MLX5E_RQ_STATE_FLUSH, &rq->state);
+	clear_bit(MLX5E_RQ_STATE_ENABLED, &rq->state);
 	napi_synchronize(&rq->channel->napi); /* prevent mlx5e_post_rx_wqes */
 	cancel_work_sync(&rq->am.work);
 
@@ -1006,7 +1008,6 @@ static int mlx5e_enable_sq(struct mlx5e_
 	MLX5_SET(sqc,  sqc, min_wqe_inline_mode, sq->min_inline_mode);
 	MLX5_SET(sqc,  sqc, state,		MLX5_SQC_STATE_RST);
 	MLX5_SET(sqc,  sqc, tis_lst_sz, param->type == MLX5E_SQ_ICO ? 0 : 1);
-	MLX5_SET(sqc,  sqc, flush_in_error_en,	1);
 
 	MLX5_SET(wq,   wq, wq_type,       MLX5_WQ_TYPE_CYCLIC);
 	MLX5_SET(wq,   wq, uar_page,      sq->uar.index);
@@ -1083,6 +1084,7 @@ static int mlx5e_open_sq(struct mlx5e_ch
 	if (err)
 		goto err_destroy_sq;
 
+	set_bit(MLX5E_SQ_STATE_ENABLED, &sq->state);
 	err = mlx5e_modify_sq(sq, MLX5_SQC_STATE_RST, MLX5_SQC_STATE_RDY,
 			      false, 0);
 	if (err)
@@ -1096,6 +1098,7 @@ static int mlx5e_open_sq(struct mlx5e_ch
 	return 0;
 
 err_disable_sq:
+	clear_bit(MLX5E_SQ_STATE_ENABLED, &sq->state);
 	mlx5e_disable_sq(sq);
 err_destroy_sq:
 	mlx5e_destroy_sq(sq);
@@ -1112,7 +1115,7 @@ static inline void netif_tx_disable_queu
 
 static void mlx5e_close_sq(struct mlx5e_sq *sq)
 {
-	set_bit(MLX5E_SQ_STATE_FLUSH, &sq->state);
+	clear_bit(MLX5E_SQ_STATE_ENABLED, &sq->state);
 	/* prevent netif_tx_wake_queue */
 	napi_synchronize(&sq->channel->napi);
 
@@ -3092,7 +3095,7 @@ static void mlx5e_tx_timeout(struct net_
 		if (!netif_xmit_stopped(netdev_get_tx_queue(dev, i)))
 			continue;
 		sched_work = true;
-		set_bit(MLX5E_SQ_STATE_FLUSH, &sq->state);
+		clear_bit(MLX5E_SQ_STATE_ENABLED, &sq->state);
 		netdev_err(dev, "TX timeout on queue: %d, SQ: 0x%x, CQ: 0x%x, SQ Cons: 0x%x SQ Prod: 0x%x\n",
 			   i, sq->sqn, sq->cq.mcq.cqn, sq->cc, sq->pc);
 	}
@@ -3147,13 +3150,13 @@ static int mlx5e_xdp_set(struct net_devi
 	for (i = 0; i < priv->params.num_channels; i++) {
 		struct mlx5e_channel *c = priv->channel[i];
 
-		set_bit(MLX5E_RQ_STATE_FLUSH, &c->rq.state);
+		clear_bit(MLX5E_RQ_STATE_ENABLED, &c->rq.state);
 		napi_synchronize(&c->napi);
 		/* prevent mlx5e_poll_rx_cq from accessing rq->xdp_prog */
 
 		old_prog = xchg(&c->rq.xdp_prog, prog);
 
-		clear_bit(MLX5E_RQ_STATE_FLUSH, &c->rq.state);
+		set_bit(MLX5E_RQ_STATE_ENABLED, &c->rq.state);
 		/* napi_schedule in case we have missed anything */
 		set_bit(MLX5E_CHANNEL_NAPI_SCHED, &c->flags);
 		napi_schedule(&c->napi);
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c linux-libre-4.9-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
--- linux-libre-4.9-rc8-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c	2016-12-11 14:17:54.000000000 -0500
@@ -340,7 +340,7 @@ static inline void mlx5e_post_umr_wqe(st
 	while ((pi = (sq->pc & wq->sz_m1)) > sq->edge) {
 		sq->db.ico_wqe[pi].opcode = MLX5_OPCODE_NOP;
 		sq->db.ico_wqe[pi].num_wqebbs = 1;
-		mlx5e_send_nop(sq, true);
+		mlx5e_send_nop(sq, false);
 	}
 
 	wqe = mlx5_wq_cyc_get_wqe(wq, pi);
@@ -412,7 +412,7 @@ void mlx5e_post_rx_mpwqe(struct mlx5e_rq
 
 	clear_bit(MLX5E_RQ_STATE_UMR_WQE_IN_PROGRESS, &rq->state);
 
-	if (unlikely(test_bit(MLX5E_RQ_STATE_FLUSH, &rq->state))) {
+	if (unlikely(!test_bit(MLX5E_RQ_STATE_ENABLED, &rq->state))) {
 		mlx5e_free_rx_mpwqe(rq, &rq->mpwqe.info[wq->head]);
 		return;
 	}
@@ -445,7 +445,7 @@ void mlx5e_dealloc_rx_mpwqe(struct mlx5e
 }
 
 #define RQ_CANNOT_POST(rq) \
-	(test_bit(MLX5E_RQ_STATE_FLUSH, &rq->state) || \
+	(!test_bit(MLX5E_RQ_STATE_ENABLED, &rq->state) || \
 	 test_bit(MLX5E_RQ_STATE_UMR_WQE_IN_PROGRESS, &rq->state))
 
 bool mlx5e_post_rx_wqes(struct mlx5e_rq *rq)
@@ -924,7 +924,7 @@ int mlx5e_poll_rx_cq(struct mlx5e_cq *cq
 	struct mlx5e_sq *xdp_sq = &rq->channel->xdp_sq;
 	int work_done = 0;
 
-	if (unlikely(test_bit(MLX5E_RQ_STATE_FLUSH, &rq->state)))
+	if (unlikely(!test_bit(MLX5E_RQ_STATE_ENABLED, &rq->state)))
 		return 0;
 
 	if (cq->decmprs_left)
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c linux-libre-4.9-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
--- linux-libre-4.9-rc8-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c	2016-12-11 14:17:54.000000000 -0500
@@ -409,7 +409,7 @@ bool mlx5e_poll_tx_cq(struct mlx5e_cq *c
 
 	sq = container_of(cq, struct mlx5e_sq, cq);
 
-	if (unlikely(test_bit(MLX5E_SQ_STATE_FLUSH, &sq->state)))
+	if (unlikely(!test_bit(MLX5E_SQ_STATE_ENABLED, &sq->state)))
 		return false;
 
 	npkts = 0;
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c linux-libre-4.9-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c
--- linux-libre-4.9-rc8-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c	2016-12-11 14:17:54.000000000 -0500
@@ -56,7 +56,7 @@ static void mlx5e_poll_ico_cq(struct mlx
 	struct mlx5_cqe64 *cqe;
 	u16 sqcc;
 
-	if (unlikely(test_bit(MLX5E_SQ_STATE_FLUSH, &sq->state)))
+	if (unlikely(!test_bit(MLX5E_SQ_STATE_ENABLED, &sq->state)))
 		return;
 
 	cqe = mlx5e_get_cqe(cq);
@@ -113,7 +113,7 @@ static inline bool mlx5e_poll_xdp_tx_cq(
 
 	sq = container_of(cq, struct mlx5e_sq, cq);
 
-	if (unlikely(test_bit(MLX5E_SQ_STATE_FLUSH, &sq->state)))
+	if (unlikely(!test_bit(MLX5E_SQ_STATE_ENABLED, &sq->state)))
 		return false;
 
 	/* sq->cc must be updated only after mlx5_cqwq_update_db_record(),
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/ethernet/mellanox/mlx5/core/Kconfig linux-libre-4.9-gnu/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
--- linux-libre-4.9-rc8-gnu/drivers/net/ethernet/mellanox/mlx5/core/Kconfig	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/ethernet/mellanox/mlx5/core/Kconfig	2016-12-11 14:17:54.000000000 -0500
@@ -18,8 +18,6 @@ config MLX5_CORE_EN
 	default n
 	---help---
 	  Ethernet support in Mellanox Technologies ConnectX-4 NIC.
-	  Ethernet and Infiniband support in ConnectX-4 are currently mutually
-	  exclusive.
 
 config MLX5_CORE_EN_DCB
 	bool "Data Center Bridging (DCB) Support"
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/ethernet/mellanox/mlx5/core/main.c linux-libre-4.9-gnu/drivers/net/ethernet/mellanox/mlx5/core/main.c
--- linux-libre-4.9-rc8-gnu/drivers/net/ethernet/mellanox/mlx5/core/main.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/ethernet/mellanox/mlx5/core/main.c	2016-12-11 14:17:54.000000000 -0500
@@ -62,13 +62,13 @@ MODULE_DESCRIPTION("Mellanox Connect-IB,
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_VERSION(DRIVER_VERSION);
 
-int mlx5_core_debug_mask;
-module_param_named(debug_mask, mlx5_core_debug_mask, int, 0644);
+unsigned int mlx5_core_debug_mask;
+module_param_named(debug_mask, mlx5_core_debug_mask, uint, 0644);
 MODULE_PARM_DESC(debug_mask, "debug mask: 1 = dump cmd data, 2 = dump cmd exec time, 3 = both. Default=0");
 
 #define MLX5_DEFAULT_PROF	2
-static int prof_sel = MLX5_DEFAULT_PROF;
-module_param_named(prof_sel, prof_sel, int, 0444);
+static unsigned int prof_sel = MLX5_DEFAULT_PROF;
+module_param_named(prof_sel, prof_sel, uint, 0444);
 MODULE_PARM_DESC(prof_sel, "profile selector. Valid range 0 - 2");
 
 enum {
@@ -732,13 +732,15 @@ static int mlx5_core_set_issi(struct mlx
 		u8 status;
 
 		mlx5_cmd_mbox_status(query_out, &status, &syndrome);
-		if (status == MLX5_CMD_STAT_BAD_OP_ERR) {
-			pr_debug("Only ISSI 0 is supported\n");
-			return 0;
+		if (!status || syndrome == MLX5_DRIVER_SYND) {
+			mlx5_core_err(dev, "Failed to query ISSI err(%d) status(%d) synd(%d)\n",
+				      err, status, syndrome);
+			return err;
 		}
 
-		pr_err("failed to query ISSI err(%d)\n", err);
-		return err;
+		mlx5_core_warn(dev, "Query ISSI is not supported by FW, ISSI is 0\n");
+		dev->issi = 0;
+		return 0;
 	}
 
 	sup_issi = MLX5_GET(query_issi_out, query_out, supported_issi_dw0);
@@ -752,7 +754,8 @@ static int mlx5_core_set_issi(struct mlx
 		err = mlx5_cmd_exec(dev, set_in, sizeof(set_in),
 				    set_out, sizeof(set_out));
 		if (err) {
-			pr_err("failed to set ISSI=1 err(%d)\n", err);
+			mlx5_core_err(dev, "Failed to set ISSI to 1 err(%d)\n",
+				      err);
 			return err;
 		}
 
@@ -1227,13 +1230,6 @@ static int init_one(struct pci_dev *pdev
 
 	dev->pdev = pdev;
 	dev->event = mlx5_core_event;
-
-	if (prof_sel < 0 || prof_sel >= ARRAY_SIZE(profile)) {
-		mlx5_core_warn(dev,
-			       "selected profile out of range, selecting default (%d)\n",
-			       MLX5_DEFAULT_PROF);
-		prof_sel = MLX5_DEFAULT_PROF;
-	}
 	dev->profile = &profile[prof_sel];
 
 	INIT_LIST_HEAD(&priv->ctx_list);
@@ -1450,10 +1446,22 @@ static struct pci_driver mlx5_core_drive
 	.sriov_configure   = mlx5_core_sriov_configure,
 };
 
+static void mlx5_core_verify_params(void)
+{
+	if (prof_sel >= ARRAY_SIZE(profile)) {
+		pr_warn("mlx5_core: WARNING: Invalid module parameter prof_sel %d, valid range 0-%zu, changing back to default(%d)\n",
+			prof_sel,
+			ARRAY_SIZE(profile) - 1,
+			MLX5_DEFAULT_PROF);
+		prof_sel = MLX5_DEFAULT_PROF;
+	}
+}
+
 static int __init init(void)
 {
 	int err;
 
+	mlx5_core_verify_params();
 	mlx5_register_debugfs();
 
 	err = pci_register_driver(&mlx5_core_driver);
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h linux-libre-4.9-gnu/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
--- linux-libre-4.9-rc8-gnu/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h	2016-12-11 14:17:54.000000000 -0500
@@ -44,11 +44,11 @@
 
 #define MLX5_TOTAL_VPORTS(mdev) (1 + pci_sriov_get_totalvfs(mdev->pdev))
 
-extern int mlx5_core_debug_mask;
+extern uint mlx5_core_debug_mask;
 
 #define mlx5_core_dbg(__dev, format, ...)				\
-	dev_dbg(&(__dev)->pdev->dev, "%s:%s:%d:(pid %d): " format,	\
-		 (__dev)->priv.name, __func__, __LINE__, current->pid,	\
+	dev_dbg(&(__dev)->pdev->dev, "%s:%d:(pid %d): " format,		\
+		 __func__, __LINE__, current->pid,			\
 		 ##__VA_ARGS__)
 
 #define mlx5_core_dbg_mask(__dev, mask, format, ...)			\
@@ -63,8 +63,8 @@ do {									\
 	       ##__VA_ARGS__)
 
 #define mlx5_core_warn(__dev, format, ...)				\
-	dev_warn(&(__dev)->pdev->dev, "%s:%s:%d:(pid %d): " format,	\
-		(__dev)->priv.name, __func__, __LINE__, current->pid,	\
+	dev_warn(&(__dev)->pdev->dev, "%s:%d:(pid %d): " format,	\
+		 __func__, __LINE__, current->pid,			\
 		##__VA_ARGS__)
 
 #define mlx5_core_info(__dev, format, ...)				\
@@ -75,6 +75,11 @@ enum {
 	MLX5_CMD_TIME, /* print command execution time */
 };
 
+enum {
+	MLX5_DRIVER_STATUS_ABORTED = 0xfe,
+	MLX5_DRIVER_SYND = 0xbadd00de,
+};
+
 int mlx5_query_hca_caps(struct mlx5_core_dev *dev);
 int mlx5_query_board_id(struct mlx5_core_dev *dev);
 int mlx5_cmd_init_hca(struct mlx5_core_dev *dev);
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/ethernet/qlogic/qed/qed_ll2.c linux-libre-4.9-gnu/drivers/net/ethernet/qlogic/qed/qed_ll2.c
--- linux-libre-4.9-rc8-gnu/drivers/net/ethernet/qlogic/qed/qed_ll2.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/ethernet/qlogic/qed/qed_ll2.c	2016-12-11 14:17:54.000000000 -0500
@@ -1730,6 +1730,7 @@ static int qed_ll2_start_xmit(struct qed
 						       mapping))) {
 				DP_NOTICE(cdev,
 					  "Unable to map frag - dropping packet\n");
+				rc = -ENOMEM;
 				goto err;
 			}
 		} else {
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/ethernet/smsc/smsc911x.c linux-libre-4.9-gnu/drivers/net/ethernet/smsc/smsc911x.c
--- linux-libre-4.9-rc8-gnu/drivers/net/ethernet/smsc/smsc911x.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/ethernet/smsc/smsc911x.c	2016-12-11 14:17:54.000000000 -0500
@@ -438,9 +438,16 @@ static int smsc911x_request_resources(st
 	ret = regulator_bulk_get(&pdev->dev,
 			ARRAY_SIZE(pdata->supplies),
 			pdata->supplies);
-	if (ret)
+	if (ret) {
+		/*
+		 * Retry on deferrals, else just report the error
+		 * and try to continue.
+		 */
+		if (ret == -EPROBE_DEFER)
+			return ret;
 		netdev_err(ndev, "couldn't get regulators %d\n",
 				ret);
+	}
 
 	/* Request optional RESET GPIO */
 	pdata->reset_gpiod = devm_gpiod_get_optional(&pdev->dev,
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c linux-libre-4.9-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
--- linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c	2016-12-11 14:17:54.000000000 -0500
@@ -43,9 +43,11 @@ static void dwmac1000_dma_axi(void __iom
 	if (axi->axi_xit_frm)
 		value |= DMA_AXI_LPI_XIT_FRM;
 
+	value &= ~DMA_AXI_WR_OSR_LMT;
 	value |= (axi->axi_wr_osr_lmt & DMA_AXI_WR_OSR_LMT_MASK) <<
 		 DMA_AXI_WR_OSR_LMT_SHIFT;
 
+	value &= ~DMA_AXI_RD_OSR_LMT;
 	value |= (axi->axi_rd_osr_lmt & DMA_AXI_RD_OSR_LMT_MASK) <<
 		 DMA_AXI_RD_OSR_LMT_SHIFT;
 
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c linux-libre-4.9-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
--- linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c	2016-12-11 14:17:54.000000000 -0500
@@ -30,9 +30,11 @@ static void dwmac4_dma_axi(void __iomem
 	if (axi->axi_xit_frm)
 		value |= DMA_AXI_LPI_XIT_FRM;
 
+	value &= ~DMA_AXI_WR_OSR_LMT;
 	value |= (axi->axi_wr_osr_lmt & DMA_AXI_OSR_MAX) <<
 		 DMA_AXI_WR_OSR_LMT_SHIFT;
 
+	value &= ~DMA_AXI_RD_OSR_LMT;
 	value |= (axi->axi_rd_osr_lmt & DMA_AXI_OSR_MAX) <<
 		 DMA_AXI_RD_OSR_LMT_SHIFT;
 
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c linux-libre-4.9-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
--- linux-libre-4.9-rc8-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c	2016-12-11 14:17:54.000000000 -0500
@@ -126,8 +126,10 @@ static struct stmmac_axi *stmmac_axi_set
 	axi->axi_mb = of_property_read_bool(np, "snps,axi_mb");
 	axi->axi_rb =  of_property_read_bool(np, "snps,axi_rb");
 
-	of_property_read_u32(np, "snps,wr_osr_lmt", &axi->axi_wr_osr_lmt);
-	of_property_read_u32(np, "snps,rd_osr_lmt", &axi->axi_rd_osr_lmt);
+	if (of_property_read_u32(np, "snps,wr_osr_lmt", &axi->axi_wr_osr_lmt))
+		axi->axi_wr_osr_lmt = 1;
+	if (of_property_read_u32(np, "snps,rd_osr_lmt", &axi->axi_rd_osr_lmt))
+		axi->axi_rd_osr_lmt = 1;
 	of_property_read_u32_array(np, "snps,blen", axi->axi_blen, AXI_BLEN);
 	of_node_put(np);
 
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/ethernet/ti/cpmac.c linux-libre-4.9-gnu/drivers/net/ethernet/ti/cpmac.c
--- linux-libre-4.9-rc8-gnu/drivers/net/ethernet/ti/cpmac.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/ethernet/ti/cpmac.c	2016-12-11 14:17:54.000000000 -0500
@@ -1113,6 +1113,7 @@ static int cpmac_probe(struct platform_d
 	if (!dev)
 		return -ENOMEM;
 
+	SET_NETDEV_DEV(dev, &pdev->dev);
 	platform_set_drvdata(pdev, dev);
 	priv = netdev_priv(dev);
 
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/ethernet/ti/cpsw-phy-sel.c linux-libre-4.9-gnu/drivers/net/ethernet/ti/cpsw-phy-sel.c
--- linux-libre-4.9-rc8-gnu/drivers/net/ethernet/ti/cpsw-phy-sel.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/ethernet/ti/cpsw-phy-sel.c	2016-12-11 14:17:54.000000000 -0500
@@ -81,6 +81,7 @@ static void cpsw_gmii_sel_am3352(struct
 	};
 
 	mask = GMII_SEL_MODE_MASK << (slave * 2) | BIT(slave + 6);
+	mask |= BIT(slave + 4);
 	mode <<= slave * 2;
 
 	if (priv->rmii_clock_external) {
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/hyperv/netvsc_drv.c linux-libre-4.9-gnu/drivers/net/hyperv/netvsc_drv.c
--- linux-libre-4.9-rc8-gnu/drivers/net/hyperv/netvsc_drv.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/hyperv/netvsc_drv.c	2016-12-11 14:17:54.000000000 -0500
@@ -47,6 +47,10 @@
 				 NETIF_F_TSO | \
 				 NETIF_F_TSO6 | \
 				 NETIF_F_HW_CSUM)
+
+/* Restrict GSO size to account for NVGRE */
+#define NETVSC_GSO_MAX_SIZE	62768
+
 static int ring_size = 128;
 module_param(ring_size, int, S_IRUGO);
 MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)");
@@ -1400,6 +1404,7 @@ static int netvsc_probe(struct hv_device
 	nvdev = net_device_ctx->nvdev;
 	netif_set_real_num_tx_queues(net, nvdev->num_chn);
 	netif_set_real_num_rx_queues(net, nvdev->num_chn);
+	netif_set_gso_max_size(net, NETVSC_GSO_MAX_SIZE);
 
 	ret = register_netdev(net);
 	if (ret != 0) {
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/ipvlan/ipvlan_main.c linux-libre-4.9-gnu/drivers/net/ipvlan/ipvlan_main.c
--- linux-libre-4.9-rc8-gnu/drivers/net/ipvlan/ipvlan_main.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/ipvlan/ipvlan_main.c	2016-12-11 14:17:54.000000000 -0500
@@ -546,13 +546,15 @@ static int ipvlan_link_new(struct net *s
 	}
 	err = ipvlan_set_port_mode(port, mode);
 	if (err) {
-		goto unregister_netdev;
+		goto unlink_netdev;
 	}
 
 	list_add_tail_rcu(&ipvlan->pnode, &port->ipvlans);
 	netif_stacked_transfer_operstate(phy_dev, dev);
 	return 0;
 
+unlink_netdev:
+	netdev_upper_dev_unlink(phy_dev, dev);
 unregister_netdev:
 	unregister_netdevice(dev);
 destroy_ipvlan_port:
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/irda/irda-usb.c linux-libre-4.9-gnu/drivers/net/irda/irda-usb.c
--- linux-libre-4.9-rc8-gnu/drivers/net/irda/irda-usb.c	2016-12-04 17:51:37.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/irda/irda-usb.c	2016-12-11 17:51:03.000000000 -0500
@@ -1720,6 +1720,7 @@ static int irda_usb_probe(struct usb_int
 	/* Don't change this buffer size and allocation without doing
 	 * some heavy and complete testing. Don't ask why :-(
 	 * Jean II */
+	ret = -ENOMEM;
 	self->speed_buff = kzalloc(IRDA_USB_SPEED_MTU, GFP_KERNEL);
 	if (!self->speed_buff)
 		goto err_out_3;
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/phy/phy_device.c linux-libre-4.9-gnu/drivers/net/phy/phy_device.c
--- linux-libre-4.9-rc8-gnu/drivers/net/phy/phy_device.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/phy/phy_device.c	2016-12-11 14:17:54.000000000 -0500
@@ -857,11 +857,17 @@ EXPORT_SYMBOL(phy_attached_print);
 int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
 		      u32 flags, phy_interface_t interface)
 {
+	struct module *ndev_owner = dev->dev.parent->driver->owner;
 	struct mii_bus *bus = phydev->mdio.bus;
 	struct device *d = &phydev->mdio.dev;
 	int err;
 
-	if (!try_module_get(bus->owner)) {
+	/* For Ethernet device drivers that register their own MDIO bus, we
+	 * will have bus->owner match ndev_mod, so we do not want to increment
+	 * our own module->refcnt here, otherwise we would not be able to
+	 * unload later on.
+	 */
+	if (ndev_owner != bus->owner && !try_module_get(bus->owner)) {
 		dev_err(&dev->dev, "failed to get the bus module\n");
 		return -EIO;
 	}
@@ -921,7 +927,8 @@ int phy_attach_direct(struct net_device
 
 error:
 	put_device(d);
-	module_put(bus->owner);
+	if (ndev_owner != bus->owner)
+		module_put(bus->owner);
 	return err;
 }
 EXPORT_SYMBOL(phy_attach_direct);
@@ -971,6 +978,8 @@ EXPORT_SYMBOL(phy_attach);
  */
 void phy_detach(struct phy_device *phydev)
 {
+	struct net_device *dev = phydev->attached_dev;
+	struct module *ndev_owner = dev->dev.parent->driver->owner;
 	struct mii_bus *bus;
 	int i;
 
@@ -998,7 +1007,8 @@ void phy_detach(struct phy_device *phyde
 	bus = phydev->mdio.bus;
 
 	put_device(&phydev->mdio.dev);
-	module_put(bus->owner);
+	if (ndev_owner != bus->owner)
+		module_put(bus->owner);
 }
 EXPORT_SYMBOL(phy_detach);
 
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/usb/cdc_mbim.c linux-libre-4.9-gnu/drivers/net/usb/cdc_mbim.c
--- linux-libre-4.9-rc8-gnu/drivers/net/usb/cdc_mbim.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/usb/cdc_mbim.c	2016-12-11 14:17:54.000000000 -0500
@@ -602,6 +602,21 @@ static const struct driver_info cdc_mbim
 	.data = CDC_NCM_FLAG_NDP_TO_END,
 };
 
+/* Some modems (e.g. Telit LE922A6) do not work properly with altsetting
+ * toggle done in cdc_ncm_bind_common. CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE
+ * flag is used to avoid this procedure.
+ */
+static const struct driver_info cdc_mbim_info_avoid_altsetting_toggle = {
+	.description = "CDC MBIM",
+	.flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET | FLAG_WWAN,
+	.bind = cdc_mbim_bind,
+	.unbind = cdc_mbim_unbind,
+	.manage_power = cdc_mbim_manage_power,
+	.rx_fixup = cdc_mbim_rx_fixup,
+	.tx_fixup = cdc_mbim_tx_fixup,
+	.data = CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE,
+};
+
 static const struct usb_device_id mbim_devs[] = {
 	/* This duplicate NCM entry is intentional. MBIM devices can
 	 * be disguised as NCM by default, and this is necessary to
@@ -626,6 +641,12 @@ static const struct usb_device_id mbim_d
 	{ USB_VENDOR_AND_INTERFACE_INFO(0x12d1, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
 	  .driver_info = (unsigned long)&cdc_mbim_info_ndp_to_end,
 	},
+
+	/* Telit LE922A6 in MBIM composition */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x1bc7, 0x1041, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
+	  .driver_info = (unsigned long)&cdc_mbim_info_avoid_altsetting_toggle,
+	},
+
 	/* default entry */
 	{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
 	  .driver_info = (unsigned long)&cdc_mbim_info_zlp,
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/usb/cdc_ncm.c linux-libre-4.9-gnu/drivers/net/usb/cdc_ncm.c
--- linux-libre-4.9-rc8-gnu/drivers/net/usb/cdc_ncm.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/usb/cdc_ncm.c	2016-12-11 14:17:54.000000000 -0500
@@ -839,11 +839,18 @@ int cdc_ncm_bind_common(struct usbnet *d
 
 	iface_no = ctx->data->cur_altsetting->desc.bInterfaceNumber;
 
+	/* Device-specific flags */
+	ctx->drvflags = drvflags;
+
 	/* Reset data interface. Some devices will not reset properly
 	 * unless they are configured first.  Toggle the altsetting to
-	 * force a reset
+	 * force a reset.
+	 * Some other devices do not work properly with this procedure
+	 * that can be avoided using quirk CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE
 	 */
-	usb_set_interface(dev->udev, iface_no, data_altsetting);
+	if (!(ctx->drvflags & CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE))
+		usb_set_interface(dev->udev, iface_no, data_altsetting);
+
 	temp = usb_set_interface(dev->udev, iface_no, 0);
 	if (temp) {
 		dev_dbg(&intf->dev, "set interface failed\n");
@@ -890,9 +897,6 @@ int cdc_ncm_bind_common(struct usbnet *d
 	/* finish setting up the device specific data */
 	cdc_ncm_setup(dev);
 
-	/* Device-specific flags */
-	ctx->drvflags = drvflags;
-
 	/* Allocate the delayed NDP if needed. */
 	if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END) {
 		ctx->delayed_ndp16 = kzalloc(ctx->max_ndp_size, GFP_KERNEL);
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/usb/lan78xx.c linux-libre-4.9-gnu/drivers/net/usb/lan78xx.c
--- linux-libre-4.9-rc8-gnu/drivers/net/usb/lan78xx.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/usb/lan78xx.c	2016-12-11 14:17:54.000000000 -0500
@@ -3395,6 +3395,7 @@ static int lan78xx_probe(struct usb_inte
 	if (buf) {
 		dev->urb_intr = usb_alloc_urb(0, GFP_KERNEL);
 		if (!dev->urb_intr) {
+			ret = -ENOMEM;
 			kfree(buf);
 			goto out3;
 		} else {
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/net/virtio_net.c linux-libre-4.9-gnu/drivers/net/virtio_net.c
--- linux-libre-4.9-rc8-gnu/drivers/net/virtio_net.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/net/virtio_net.c	2016-12-11 14:17:54.000000000 -0500
@@ -969,12 +969,17 @@ static int virtnet_set_mac_address(struc
 	struct virtnet_info *vi = netdev_priv(dev);
 	struct virtio_device *vdev = vi->vdev;
 	int ret;
-	struct sockaddr *addr = p;
+	struct sockaddr *addr;
 	struct scatterlist sg;
 
-	ret = eth_prepare_mac_addr_change(dev, p);
+	addr = kmalloc(sizeof(*addr), GFP_KERNEL);
+	if (!addr)
+		return -ENOMEM;
+	memcpy(addr, p, sizeof(*addr));
+
+	ret = eth_prepare_mac_addr_change(dev, addr);
 	if (ret)
-		return ret;
+		goto out;
 
 	if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR)) {
 		sg_init_one(&sg, addr->sa_data, dev->addr_len);
@@ -982,7 +987,8 @@ static int virtnet_set_mac_address(struc
 					  VIRTIO_NET_CTRL_MAC_ADDR_SET, &sg)) {
 			dev_warn(&vdev->dev,
 				 "Failed to set mac address by vq command.\n");
-			return -EINVAL;
+			ret = -EINVAL;
+			goto out;
 		}
 	} else if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC) &&
 		   !virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
@@ -996,8 +1002,11 @@ static int virtnet_set_mac_address(struc
 	}
 
 	eth_commit_mac_addr_change(dev, p);
+	ret = 0;
 
-	return 0;
+out:
+	kfree(addr);
+	return ret;
 }
 
 static struct rtnl_link_stats64 *virtnet_stats(struct net_device *dev,
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/nvdimm/bus.c linux-libre-4.9-gnu/drivers/nvdimm/bus.c
--- linux-libre-4.9-rc8-gnu/drivers/nvdimm/bus.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/nvdimm/bus.c	2016-12-11 14:17:54.000000000 -0500
@@ -715,7 +715,7 @@ EXPORT_SYMBOL_GPL(nd_cmd_in_size);
 
 u32 nd_cmd_out_size(struct nvdimm *nvdimm, int cmd,
 		const struct nd_cmd_desc *desc, int idx, const u32 *in_field,
-		const u32 *out_field)
+		const u32 *out_field, unsigned long remainder)
 {
 	if (idx >= desc->out_num)
 		return UINT_MAX;
@@ -727,9 +727,24 @@ u32 nd_cmd_out_size(struct nvdimm *nvdim
 		return in_field[1];
 	else if (nvdimm && cmd == ND_CMD_VENDOR && idx == 2)
 		return out_field[1];
-	else if (!nvdimm && cmd == ND_CMD_ARS_STATUS && idx == 2)
-		return out_field[1] - 8;
-	else if (cmd == ND_CMD_CALL) {
+	else if (!nvdimm && cmd == ND_CMD_ARS_STATUS && idx == 2) {
+		/*
+		 * Per table 9-276 ARS Data in ACPI 6.1, out_field[1] is
+		 * "Size of Output Buffer in bytes, including this
+		 * field."
+		 */
+		if (out_field[1] < 4)
+			return 0;
+		/*
+		 * ACPI 6.1 is ambiguous if 'status' is included in the
+		 * output size. If we encounter an output size that
+		 * overshoots the remainder by 4 bytes, assume it was
+		 * including 'status'.
+		 */
+		if (out_field[1] - 8 == remainder)
+			return remainder;
+		return out_field[1] - 4;
+	} else if (cmd == ND_CMD_CALL) {
 		struct nd_cmd_pkg *pkg = (struct nd_cmd_pkg *) in_field;
 
 		return pkg->nd_size_out;
@@ -876,7 +891,7 @@ static int __nd_ioctl(struct nvdimm_bus
 	/* process an output envelope */
 	for (i = 0; i < desc->out_num; i++) {
 		u32 out_size = nd_cmd_out_size(nvdimm, cmd, desc, i,
-				(u32 *) in_env, (u32 *) out_env);
+				(u32 *) in_env, (u32 *) out_env, 0);
 		u32 copy;
 
 		if (out_size == UINT_MAX) {
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/scsi/lpfc/lpfc_sli.c linux-libre-4.9-gnu/drivers/scsi/lpfc/lpfc_sli.c
--- linux-libre-4.9-rc8-gnu/drivers/scsi/lpfc/lpfc_sli.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/scsi/lpfc/lpfc_sli.c	2016-12-11 14:17:54.000000000 -0500
@@ -1323,18 +1323,20 @@ lpfc_sli_ringtxcmpl_put(struct lpfc_hba
 {
 	lockdep_assert_held(&phba->hbalock);
 
-	BUG_ON(!piocb || !piocb->vport);
+	BUG_ON(!piocb);
 
 	list_add_tail(&piocb->list, &pring->txcmplq);
 	piocb->iocb_flag |= LPFC_IO_ON_TXCMPLQ;
 
 	if ((unlikely(pring->ringno == LPFC_ELS_RING)) &&
 	   (piocb->iocb.ulpCommand != CMD_ABORT_XRI_CN) &&
-	   (piocb->iocb.ulpCommand != CMD_CLOSE_XRI_CN) &&
-	    (!(piocb->vport->load_flag & FC_UNLOADING)))
-		mod_timer(&piocb->vport->els_tmofunc,
-			  jiffies +
-			  msecs_to_jiffies(1000 * (phba->fc_ratov << 1)));
+	   (piocb->iocb.ulpCommand != CMD_CLOSE_XRI_CN)) {
+		BUG_ON(!piocb->vport);
+		if (!(piocb->vport->load_flag & FC_UNLOADING))
+			mod_timer(&piocb->vport->els_tmofunc,
+				  jiffies +
+				  msecs_to_jiffies(1000 * (phba->fc_ratov << 1)));
+	}
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/drivers/vhost/vsock.c linux-libre-4.9-gnu/drivers/vhost/vsock.c
--- linux-libre-4.9-rc8-gnu/drivers/vhost/vsock.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/drivers/vhost/vsock.c	2016-12-11 14:17:54.000000000 -0500
@@ -506,7 +506,7 @@ static void vhost_vsock_reset_orphans(st
 	 * executing.
 	 */
 
-	if (!vhost_vsock_get(vsk->local_addr.svm_cid)) {
+	if (!vhost_vsock_get(vsk->remote_addr.svm_cid)) {
 		sock_set_flag(sk, SOCK_DONE);
 		vsk->peer_shutdown = SHUTDOWN_MASK;
 		sk->sk_state = SS_UNCONNECTED;
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/fs/ceph/dir.c linux-libre-4.9-gnu/fs/ceph/dir.c
--- linux-libre-4.9-rc8-gnu/fs/ceph/dir.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/fs/ceph/dir.c	2016-12-11 14:17:54.000000000 -0500
@@ -1261,26 +1261,30 @@ static int ceph_d_revalidate(struct dent
 			return -ECHILD;
 
 		op = ceph_snap(dir) == CEPH_SNAPDIR ?
-			CEPH_MDS_OP_LOOKUPSNAP : CEPH_MDS_OP_LOOKUP;
+			CEPH_MDS_OP_LOOKUPSNAP : CEPH_MDS_OP_GETATTR;
 		req = ceph_mdsc_create_request(mdsc, op, USE_ANY_MDS);
 		if (!IS_ERR(req)) {
 			req->r_dentry = dget(dentry);
-			req->r_num_caps = 2;
+			req->r_num_caps = op == CEPH_MDS_OP_GETATTR ? 1 : 2;
 
 			mask = CEPH_STAT_CAP_INODE | CEPH_CAP_AUTH_SHARED;
 			if (ceph_security_xattr_wanted(dir))
 				mask |= CEPH_CAP_XATTR_SHARED;
 			req->r_args.getattr.mask = mask;
 
-			req->r_locked_dir = dir;
 			err = ceph_mdsc_do_request(mdsc, NULL, req);
-			if (err == 0 || err == -ENOENT) {
-				if (dentry == req->r_dentry) {
-					valid = !d_unhashed(dentry);
-				} else {
-					d_invalidate(req->r_dentry);
-					err = -EAGAIN;
-				}
+			switch (err) {
+			case 0:
+				if (d_really_is_positive(dentry) &&
+				    d_inode(dentry) == req->r_target_inode)
+					valid = 1;
+				break;
+			case -ENOENT:
+				if (d_really_is_negative(dentry))
+					valid = 1;
+				/* Fallthrough */
+			default:
+				break;
 			}
 			ceph_mdsc_put_request(req);
 			dout("d_revalidate %p lookup result=%d\n",
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/fs/fuse/dir.c linux-libre-4.9-gnu/fs/fuse/dir.c
--- linux-libre-4.9-rc8-gnu/fs/fuse/dir.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/fs/fuse/dir.c	2016-12-11 14:17:54.000000000 -0500
@@ -1739,8 +1739,6 @@ static int fuse_setattr(struct dentry *e
 		 * This should be done on write(), truncate() and chown().
 		 */
 		if (!fc->handle_killpriv) {
-			int kill;
-
 			/*
 			 * ia_mode calculation may have used stale i_mode.
 			 * Refresh and recalculate.
@@ -1750,12 +1748,11 @@ static int fuse_setattr(struct dentry *e
 				return ret;
 
 			attr->ia_mode = inode->i_mode;
-			kill = should_remove_suid(entry);
-			if (kill & ATTR_KILL_SUID) {
+			if (inode->i_mode & S_ISUID) {
 				attr->ia_valid |= ATTR_MODE;
 				attr->ia_mode &= ~S_ISUID;
 			}
-			if (kill & ATTR_KILL_SGID) {
+			if ((inode->i_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
 				attr->ia_valid |= ATTR_MODE;
 				attr->ia_mode &= ~S_ISGID;
 			}
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/include/asm-generic/export.h linux-libre-4.9-gnu/include/asm-generic/export.h
--- linux-libre-4.9-rc8-gnu/include/asm-generic/export.h	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/include/asm-generic/export.h	2016-12-11 14:17:54.000000000 -0500
@@ -54,7 +54,6 @@ KSYM(__kstrtab_\name):
 KSYM(__kcrctab_\name):
 	__put KSYM(__crc_\name)
 	.weak KSYM(__crc_\name)
-	.set KSYM(__crc_\name), 0
 	.previous
 #endif
 #endif
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/include/crypto/drbg.h linux-libre-4.9-gnu/include/crypto/drbg.h
--- linux-libre-4.9-rc8-gnu/include/crypto/drbg.h	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/include/crypto/drbg.h	2016-12-11 14:17:54.000000000 -0500
@@ -124,6 +124,8 @@ struct drbg_state {
 	struct skcipher_request *ctr_req;	/* CTR mode request handle */
 	__u8 *ctr_null_value_buf;		/* CTR mode unaligned buffer */
 	__u8 *ctr_null_value;			/* CTR mode aligned zero buf */
+	__u8 *outscratchpadbuf;			/* CTR mode output scratchpad */
+        __u8 *outscratchpad;			/* CTR mode aligned outbuf */
 	struct completion ctr_completion;	/* CTR mode async handler */
 	int ctr_async_err;			/* CTR mode async error */
 
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/include/linux/libnvdimm.h linux-libre-4.9-gnu/include/linux/libnvdimm.h
--- linux-libre-4.9-rc8-gnu/include/linux/libnvdimm.h	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/include/linux/libnvdimm.h	2016-12-11 14:17:54.000000000 -0500
@@ -143,7 +143,7 @@ u32 nd_cmd_in_size(struct nvdimm *nvdimm
 		const struct nd_cmd_desc *desc, int idx, void *buf);
 u32 nd_cmd_out_size(struct nvdimm *nvdimm, int cmd,
 		const struct nd_cmd_desc *desc, int idx, const u32 *in_field,
-		const u32 *out_field);
+		const u32 *out_field, unsigned long remainder);
 int nvdimm_bus_check_dimm_count(struct nvdimm_bus *nvdimm_bus, int dimm_count);
 struct nd_region *nvdimm_pmem_region_create(struct nvdimm_bus *nvdimm_bus,
 		struct nd_region_desc *ndr_desc);
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/include/linux/usb/cdc_ncm.h linux-libre-4.9-gnu/include/linux/usb/cdc_ncm.h
--- linux-libre-4.9-rc8-gnu/include/linux/usb/cdc_ncm.h	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/include/linux/usb/cdc_ncm.h	2016-12-11 14:17:54.000000000 -0500
@@ -81,7 +81,8 @@
 #define CDC_NCM_TIMER_INTERVAL_MAX		(U32_MAX / NSEC_PER_USEC)
 
 /* Driver flags */
-#define CDC_NCM_FLAG_NDP_TO_END	0x02		/* NDP is placed at end of frame */
+#define CDC_NCM_FLAG_NDP_TO_END			0x02	/* NDP is placed at end of frame */
+#define CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE	0x04	/* Avoid altsetting toggle during init */
 
 #define cdc_ncm_comm_intf_is_mbim(x)  ((x)->desc.bInterfaceSubClass == USB_CDC_SUBCLASS_MBIM && \
 				       (x)->desc.bInterfaceProtocol == USB_CDC_PROTO_NONE)
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/include/uapi/linux/can.h linux-libre-4.9-gnu/include/uapi/linux/can.h
--- linux-libre-4.9-rc8-gnu/include/uapi/linux/can.h	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/include/uapi/linux/can.h	2016-12-11 14:17:54.000000000 -0500
@@ -196,5 +196,6 @@ struct can_filter {
 };
 
 #define CAN_INV_FILTER 0x20000000U /* to be set in can_filter.can_id */
+#define CAN_RAW_FILTER_MAX 512 /* maximum number of can_filter set via setsockopt() */
 
 #endif /* !_UAPI_CAN_H */
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/include/uapi/linux/if.h linux-libre-4.9-gnu/include/uapi/linux/if.h
--- linux-libre-4.9-rc8-gnu/include/uapi/linux/if.h	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/include/uapi/linux/if.h	2016-12-11 14:17:54.000000000 -0500
@@ -31,7 +31,7 @@
 #include <linux/hdlc/ioctl.h>
 
 /* For glibc compatibility. An empty enum does not compile. */
-#if __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO != 0 && \
+#if __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO != 0 || \
     __UAPI_DEF_IF_NET_DEVICE_FLAGS != 0
 /**
  * enum net_device_flags - &struct net_device flags
@@ -99,7 +99,7 @@ enum net_device_flags {
 	IFF_ECHO			= 1<<18, /* volatile */
 #endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */
 };
-#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO != 0 && __UAPI_DEF_IF_NET_DEVICE_FLAGS != 0 */
+#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO != 0 || __UAPI_DEF_IF_NET_DEVICE_FLAGS != 0 */
 
 /* for compatibility with glibc net/if.h */
 #if __UAPI_DEF_IF_NET_DEVICE_FLAGS
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/include/uapi/linux/netfilter/Kbuild linux-libre-4.9-gnu/include/uapi/linux/netfilter/Kbuild
--- linux-libre-4.9-rc8-gnu/include/uapi/linux/netfilter/Kbuild	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/include/uapi/linux/netfilter/Kbuild	2016-12-11 14:17:54.000000000 -0500
@@ -5,6 +5,7 @@ header-y += nf_conntrack_ftp.h
 header-y += nf_conntrack_sctp.h
 header-y += nf_conntrack_tcp.h
 header-y += nf_conntrack_tuple_common.h
+header-y += nf_log.h
 header-y += nf_tables.h
 header-y += nf_tables_compat.h
 header-y += nf_nat.h
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/include/uapi/linux/tc_act/Kbuild linux-libre-4.9-gnu/include/uapi/linux/tc_act/Kbuild
--- linux-libre-4.9-rc8-gnu/include/uapi/linux/tc_act/Kbuild	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/include/uapi/linux/tc_act/Kbuild	2016-12-11 14:17:54.000000000 -0500
@@ -12,3 +12,4 @@ header-y += tc_bpf.h
 header-y += tc_connmark.h
 header-y += tc_ife.h
 header-y += tc_tunnel_key.h
+header-y += tc_skbmod.h
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/kernel/events/core.c linux-libre-4.9-gnu/kernel/events/core.c
--- linux-libre-4.9-rc8-gnu/kernel/events/core.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/kernel/events/core.c	2016-12-11 14:17:54.000000000 -0500
@@ -903,17 +903,14 @@ list_update_cgroup_event(struct perf_eve
 	 */
 	cpuctx = __get_cpu_context(ctx);
 
-	/* Only set/clear cpuctx->cgrp if current task uses event->cgrp. */
-	if (perf_cgroup_from_task(current, ctx) != event->cgrp) {
-		/*
-		 * We are removing the last cpu event in this context.
-		 * If that event is not active in this cpu, cpuctx->cgrp
-		 * should've been cleared by perf_cgroup_switch.
-		 */
-		WARN_ON_ONCE(!add && cpuctx->cgrp);
-		return;
-	}
-	cpuctx->cgrp = add ? event->cgrp : NULL;
+	/*
+	 * cpuctx->cgrp is NULL until a cgroup event is sched in or
+	 * ctx->nr_cgroup == 0 .
+	 */
+	if (add && perf_cgroup_from_task(current, ctx) == event->cgrp)
+		cpuctx->cgrp = event->cgrp;
+	else if (!add)
+		cpuctx->cgrp = NULL;
 }
 
 #else /* !CONFIG_CGROUP_PERF */
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/kernel/kcov.c linux-libre-4.9-gnu/kernel/kcov.c
--- linux-libre-4.9-rc8-gnu/kernel/kcov.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/kernel/kcov.c	2016-12-11 14:17:54.000000000 -0500
@@ -7,6 +7,7 @@
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/printk.h>
+#include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/vmalloc.h>
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/kernel/locking/lockdep.c linux-libre-4.9-gnu/kernel/locking/lockdep.c
--- linux-libre-4.9-rc8-gnu/kernel/locking/lockdep.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/kernel/locking/lockdep.c	2016-12-11 14:17:54.000000000 -0500
@@ -506,13 +506,13 @@ static void __print_lock_name(struct loc
 	name = class->name;
 	if (!name) {
 		name = __get_key_name(class->key, str);
-		printk("%s", name);
+		printk(KERN_CONT "%s", name);
 	} else {
-		printk("%s", name);
+		printk(KERN_CONT "%s", name);
 		if (class->name_version > 1)
-			printk("#%d", class->name_version);
+			printk(KERN_CONT "#%d", class->name_version);
 		if (class->subclass)
-			printk("/%d", class->subclass);
+			printk(KERN_CONT "/%d", class->subclass);
 	}
 }
 
@@ -522,9 +522,9 @@ static void print_lock_name(struct lock_
 
 	get_usage_chars(class, usage);
 
-	printk(" (");
+	printk(KERN_CONT " (");
 	__print_lock_name(class);
-	printk("){%s}", usage);
+	printk(KERN_CONT "){%s}", usage);
 }
 
 static void print_lockdep_cache(struct lockdep_map *lock)
@@ -536,7 +536,7 @@ static void print_lockdep_cache(struct l
 	if (!name)
 		name = __get_key_name(lock->key->subkeys, str);
 
-	printk("%s", name);
+	printk(KERN_CONT "%s", name);
 }
 
 static void print_lock(struct held_lock *hlock)
@@ -551,13 +551,13 @@ static void print_lock(struct held_lock
 	barrier();
 
 	if (!class_idx || (class_idx - 1) >= MAX_LOCKDEP_KEYS) {
-		printk("<RELEASED>\n");
+		printk(KERN_CONT "<RELEASED>\n");
 		return;
 	}
 
 	print_lock_name(lock_classes + class_idx - 1);
-	printk(", at: ");
-	print_ip_sym(hlock->acquire_ip);
+	printk(KERN_CONT ", at: [<%p>] %pS\n",
+		(void *)hlock->acquire_ip, (void *)hlock->acquire_ip);
 }
 
 static void lockdep_print_held_locks(struct task_struct *curr)
@@ -792,8 +792,8 @@ register_lock_class(struct lockdep_map *
 
 		printk("\nnew class %p: %s", class->key, class->name);
 		if (class->name_version > 1)
-			printk("#%d", class->name_version);
-		printk("\n");
+			printk(KERN_CONT "#%d", class->name_version);
+		printk(KERN_CONT "\n");
 		dump_stack();
 
 		if (!graph_lock()) {
@@ -1071,7 +1071,7 @@ print_circular_bug_entry(struct lock_lis
 		return 0;
 	printk("\n-> #%u", depth);
 	print_lock_name(target->class);
-	printk(":\n");
+	printk(KERN_CONT ":\n");
 	print_stack_trace(&target->trace, 6);
 
 	return 0;
@@ -1102,11 +1102,11 @@ print_circular_lock_scenario(struct held
 	if (parent != source) {
 		printk("Chain exists of:\n  ");
 		__print_lock_name(source);
-		printk(" --> ");
+		printk(KERN_CONT " --> ");
 		__print_lock_name(parent);
-		printk(" --> ");
+		printk(KERN_CONT " --> ");
 		__print_lock_name(target);
-		printk("\n\n");
+		printk(KERN_CONT "\n\n");
 	}
 
 	printk(" Possible unsafe locking scenario:\n\n");
@@ -1114,16 +1114,16 @@ print_circular_lock_scenario(struct held
 	printk("       ----                    ----\n");
 	printk("  lock(");
 	__print_lock_name(target);
-	printk(");\n");
+	printk(KERN_CONT ");\n");
 	printk("                               lock(");
 	__print_lock_name(parent);
-	printk(");\n");
+	printk(KERN_CONT ");\n");
 	printk("                               lock(");
 	__print_lock_name(target);
-	printk(");\n");
+	printk(KERN_CONT ");\n");
 	printk("  lock(");
 	__print_lock_name(source);
-	printk(");\n");
+	printk(KERN_CONT ");\n");
 	printk("\n *** DEADLOCK ***\n\n");
 }
 
@@ -1359,22 +1359,22 @@ static void print_lock_class_header(stru
 
 	printk("%*s->", depth, "");
 	print_lock_name(class);
-	printk(" ops: %lu", class->ops);
-	printk(" {\n");
+	printk(KERN_CONT " ops: %lu", class->ops);
+	printk(KERN_CONT " {\n");
 
 	for (bit = 0; bit < LOCK_USAGE_STATES; bit++) {
 		if (class->usage_mask & (1 << bit)) {
 			int len = depth;
 
 			len += printk("%*s   %s", depth, "", usage_str[bit]);
-			len += printk(" at:\n");
+			len += printk(KERN_CONT " at:\n");
 			print_stack_trace(class->usage_traces + bit, len);
 		}
 	}
 	printk("%*s }\n", depth, "");
 
-	printk("%*s ... key      at: ",depth,"");
-	print_ip_sym((unsigned long)class->key);
+	printk("%*s ... key      at: [<%p>] %pS\n",
+		depth, "", class->key, class->key);
 }
 
 /*
@@ -1437,11 +1437,11 @@ print_irq_lock_scenario(struct lock_list
 	if (middle_class != unsafe_class) {
 		printk("Chain exists of:\n  ");
 		__print_lock_name(safe_class);
-		printk(" --> ");
+		printk(KERN_CONT " --> ");
 		__print_lock_name(middle_class);
-		printk(" --> ");
+		printk(KERN_CONT " --> ");
 		__print_lock_name(unsafe_class);
-		printk("\n\n");
+		printk(KERN_CONT "\n\n");
 	}
 
 	printk(" Possible interrupt unsafe locking scenario:\n\n");
@@ -1449,18 +1449,18 @@ print_irq_lock_scenario(struct lock_list
 	printk("       ----                    ----\n");
 	printk("  lock(");
 	__print_lock_name(unsafe_class);
-	printk(");\n");
+	printk(KERN_CONT ");\n");
 	printk("                               local_irq_disable();\n");
 	printk("                               lock(");
 	__print_lock_name(safe_class);
-	printk(");\n");
+	printk(KERN_CONT ");\n");
 	printk("                               lock(");
 	__print_lock_name(middle_class);
-	printk(");\n");
+	printk(KERN_CONT ");\n");
 	printk("  <Interrupt>\n");
 	printk("    lock(");
 	__print_lock_name(safe_class);
-	printk(");\n");
+	printk(KERN_CONT ");\n");
 	printk("\n *** DEADLOCK ***\n\n");
 }
 
@@ -1497,9 +1497,9 @@ print_bad_irq_dependency(struct task_str
 	print_lock(prev);
 	printk("which would create a new lock dependency:\n");
 	print_lock_name(hlock_class(prev));
-	printk(" ->");
+	printk(KERN_CONT " ->");
 	print_lock_name(hlock_class(next));
-	printk("\n");
+	printk(KERN_CONT "\n");
 
 	printk("\nbut this new dependency connects a %s-irq-safe lock:\n",
 		irqclass);
@@ -1521,8 +1521,7 @@ print_bad_irq_dependency(struct task_str
 
 	lockdep_print_held_locks(curr);
 
-	printk("\nthe dependencies between %s-irq-safe lock", irqclass);
-	printk(" and the holding lock:\n");
+	printk("\nthe dependencies between %s-irq-safe lock and the holding lock:\n", irqclass);
 	if (!save_trace(&prev_root->trace))
 		return 0;
 	print_shortest_lock_dependencies(backwards_entry, prev_root);
@@ -1694,10 +1693,10 @@ print_deadlock_scenario(struct held_lock
 	printk("       ----\n");
 	printk("  lock(");
 	__print_lock_name(prev);
-	printk(");\n");
+	printk(KERN_CONT ");\n");
 	printk("  lock(");
 	__print_lock_name(next);
-	printk(");\n");
+	printk(KERN_CONT ");\n");
 	printk("\n *** DEADLOCK ***\n\n");
 	printk(" May be due to missing lock nesting notation\n\n");
 }
@@ -1891,9 +1890,9 @@ check_prev_add(struct task_struct *curr,
 		graph_unlock();
 		printk("\n new dependency: ");
 		print_lock_name(hlock_class(prev));
-		printk(" => ");
+		printk(KERN_CONT " => ");
 		print_lock_name(hlock_class(next));
-		printk("\n");
+		printk(KERN_CONT "\n");
 		dump_stack();
 		return graph_lock();
 	}
@@ -2343,11 +2342,11 @@ print_usage_bug_scenario(struct held_loc
 	printk("       ----\n");
 	printk("  lock(");
 	__print_lock_name(class);
-	printk(");\n");
+	printk(KERN_CONT ");\n");
 	printk("  <Interrupt>\n");
 	printk("    lock(");
 	__print_lock_name(class);
-	printk(");\n");
+	printk(KERN_CONT ");\n");
 	printk("\n *** DEADLOCK ***\n\n");
 }
 
@@ -2522,14 +2521,18 @@ check_usage_backwards(struct task_struct
 void print_irqtrace_events(struct task_struct *curr)
 {
 	printk("irq event stamp: %u\n", curr->irq_events);
-	printk("hardirqs last  enabled at (%u): ", curr->hardirq_enable_event);
-	print_ip_sym(curr->hardirq_enable_ip);
-	printk("hardirqs last disabled at (%u): ", curr->hardirq_disable_event);
-	print_ip_sym(curr->hardirq_disable_ip);
-	printk("softirqs last  enabled at (%u): ", curr->softirq_enable_event);
-	print_ip_sym(curr->softirq_enable_ip);
-	printk("softirqs last disabled at (%u): ", curr->softirq_disable_event);
-	print_ip_sym(curr->softirq_disable_ip);
+	printk("hardirqs last  enabled at (%u): [<%p>] %pS\n",
+		curr->hardirq_enable_event, (void *)curr->hardirq_enable_ip,
+		(void *)curr->hardirq_enable_ip);
+	printk("hardirqs last disabled at (%u): [<%p>] %pS\n",
+		curr->hardirq_disable_event, (void *)curr->hardirq_disable_ip,
+		(void *)curr->hardirq_disable_ip);
+	printk("softirqs last  enabled at (%u): [<%p>] %pS\n",
+		curr->softirq_enable_event, (void *)curr->softirq_enable_ip,
+		(void *)curr->softirq_enable_ip);
+	printk("softirqs last disabled at (%u): [<%p>] %pS\n",
+		curr->softirq_disable_event, (void *)curr->softirq_disable_ip,
+		(void *)curr->softirq_disable_ip);
 }
 
 static int HARDIRQ_verbose(struct lock_class *class)
@@ -3235,8 +3238,8 @@ static int __lock_acquire(struct lockdep
 	if (very_verbose(class)) {
 		printk("\nacquire class [%p] %s", class->key, class->name);
 		if (class->name_version > 1)
-			printk("#%d", class->name_version);
-		printk("\n");
+			printk(KERN_CONT "#%d", class->name_version);
+		printk(KERN_CONT "\n");
 		dump_stack();
 	}
 
@@ -3378,7 +3381,7 @@ print_unlock_imbalance_bug(struct task_s
 	printk("%s/%d is trying to release lock (",
 		curr->comm, task_pid_nr(curr));
 	print_lockdep_cache(lock);
-	printk(") at:\n");
+	printk(KERN_CONT ") at:\n");
 	print_ip_sym(ip);
 	printk("but there are no more locks to release!\n");
 	printk("\nother info that might help us debug this:\n");
@@ -3871,7 +3874,7 @@ print_lock_contention_bug(struct task_st
 	printk("%s/%d is trying to contend lock (",
 		curr->comm, task_pid_nr(curr));
 	print_lockdep_cache(lock);
-	printk(") at:\n");
+	printk(KERN_CONT ") at:\n");
 	print_ip_sym(ip);
 	printk("but there are no locks held!\n");
 	printk("\nother info that might help us debug this:\n");
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/kernel/locking/rtmutex.c linux-libre-4.9-gnu/kernel/locking/rtmutex.c
--- linux-libre-4.9-rc8-gnu/kernel/locking/rtmutex.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/kernel/locking/rtmutex.c	2016-12-11 14:17:54.000000000 -0500
@@ -65,8 +65,72 @@ static inline void clear_rt_mutex_waiter
 
 static void fixup_rt_mutex_waiters(struct rt_mutex *lock)
 {
-	if (!rt_mutex_has_waiters(lock))
-		clear_rt_mutex_waiters(lock);
+	unsigned long owner, *p = (unsigned long *) &lock->owner;
+
+	if (rt_mutex_has_waiters(lock))
+		return;
+
+	/*
+	 * The rbtree has no waiters enqueued, now make sure that the
+	 * lock->owner still has the waiters bit set, otherwise the
+	 * following can happen:
+	 *
+	 * CPU 0	CPU 1		CPU2
+	 * l->owner=T1
+	 *		rt_mutex_lock(l)
+	 *		lock(l->lock)
+	 *		l->owner = T1 | HAS_WAITERS;
+	 *		enqueue(T2)
+	 *		boost()
+	 *		  unlock(l->lock)
+	 *		block()
+	 *
+	 *				rt_mutex_lock(l)
+	 *				lock(l->lock)
+	 *				l->owner = T1 | HAS_WAITERS;
+	 *				enqueue(T3)
+	 *				boost()
+	 *				  unlock(l->lock)
+	 *				block()
+	 *		signal(->T2)	signal(->T3)
+	 *		lock(l->lock)
+	 *		dequeue(T2)
+	 *		deboost()
+	 *		  unlock(l->lock)
+	 *				lock(l->lock)
+	 *				dequeue(T3)
+	 *				 ==> wait list is empty
+	 *				deboost()
+	 *				 unlock(l->lock)
+	 *		lock(l->lock)
+	 *		fixup_rt_mutex_waiters()
+	 *		  if (wait_list_empty(l) {
+	 *		    l->owner = owner
+	 *		    owner = l->owner & ~HAS_WAITERS;
+	 *		      ==> l->owner = T1
+	 *		  }
+	 *				lock(l->lock)
+	 * rt_mutex_unlock(l)		fixup_rt_mutex_waiters()
+	 *				  if (wait_list_empty(l) {
+	 *				    owner = l->owner & ~HAS_WAITERS;
+	 * cmpxchg(l->owner, T1, NULL)
+	 *  ===> Success (l->owner = NULL)
+	 *
+	 *				    l->owner = owner
+	 *				      ==> l->owner = T1
+	 *				  }
+	 *
+	 * With the check for the waiter bit in place T3 on CPU2 will not
+	 * overwrite. All tasks fiddling with the waiters bit are
+	 * serialized by l->lock, so nothing else can modify the waiters
+	 * bit. If the bit is set then nothing can change l->owner either
+	 * so the simple RMW is safe. The cmpxchg() will simply fail if it
+	 * happens in the middle of the RMW because the waiters bit is
+	 * still set.
+	 */
+	owner = READ_ONCE(*p);
+	if (owner & RT_MUTEX_HAS_WAITERS)
+		WRITE_ONCE(*p, owner & ~RT_MUTEX_HAS_WAITERS);
 }
 
 /*
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/kernel/locking/rtmutex_common.h linux-libre-4.9-gnu/kernel/locking/rtmutex_common.h
--- linux-libre-4.9-rc8-gnu/kernel/locking/rtmutex_common.h	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/kernel/locking/rtmutex_common.h	2016-12-11 14:17:54.000000000 -0500
@@ -75,8 +75,9 @@ task_top_pi_waiter(struct task_struct *p
 
 static inline struct task_struct *rt_mutex_owner(struct rt_mutex *lock)
 {
-	return (struct task_struct *)
-		((unsigned long)lock->owner & ~RT_MUTEX_OWNER_MASKALL);
+	unsigned long owner = (unsigned long) READ_ONCE(lock->owner);
+
+	return (struct task_struct *) (owner & ~RT_MUTEX_OWNER_MASKALL);
 }
 
 /*
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/kernel/sched/auto_group.c linux-libre-4.9-gnu/kernel/sched/auto_group.c
--- linux-libre-4.9-rc8-gnu/kernel/sched/auto_group.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/kernel/sched/auto_group.c	2016-12-11 14:17:54.000000000 -0500
@@ -212,6 +212,7 @@ int proc_sched_autogroup_set_nice(struct
 {
 	static unsigned long next = INITIAL_JIFFIES;
 	struct autogroup *ag;
+	unsigned long shares;
 	int err;
 
 	if (nice < MIN_NICE || nice > MAX_NICE)
@@ -230,9 +231,10 @@ int proc_sched_autogroup_set_nice(struct
 
 	next = HZ / 10 + jiffies;
 	ag = autogroup_task_get(p);
+	shares = scale_load(sched_prio_to_weight[nice + 20]);
 
 	down_write(&ag->lock);
-	err = sched_group_set_shares(ag->tg, sched_prio_to_weight[nice + 20]);
+	err = sched_group_set_shares(ag->tg, shares);
 	if (!err)
 		ag->nice = nice;
 	up_write(&ag->lock);
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/lib/locking-selftest.c linux-libre-4.9-gnu/lib/locking-selftest.c
--- linux-libre-4.9-rc8-gnu/lib/locking-selftest.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/lib/locking-selftest.c	2016-12-11 14:17:54.000000000 -0500
@@ -980,23 +980,23 @@ static void dotest(void (*testcase_fn)(v
 #ifndef CONFIG_PROVE_LOCKING
 	if (expected == FAILURE && debug_locks) {
 		expected_testcase_failures++;
-		printk("failed|");
+		pr_cont("failed|");
 	}
 	else
 #endif
 	if (debug_locks != expected) {
 		unexpected_testcase_failures++;
-		printk("FAILED|");
+		pr_cont("FAILED|");
 
 		dump_stack();
 	} else {
 		testcase_successes++;
-		printk("  ok  |");
+		pr_cont("  ok  |");
 	}
 	testcase_total++;
 
 	if (debug_locks_verbose)
-		printk(" lockclass mask: %x, debug_locks: %d, expected: %d\n",
+		pr_cont(" lockclass mask: %x, debug_locks: %d, expected: %d\n",
 			lockclass_mask, debug_locks, expected);
 	/*
 	 * Some tests (e.g. double-unlock) might corrupt the preemption
@@ -1021,26 +1021,26 @@ static inline void print_testname(const
 #define DO_TESTCASE_1(desc, name, nr)				\
 	print_testname(desc"/"#nr);				\
 	dotest(name##_##nr, SUCCESS, LOCKTYPE_RWLOCK);		\
-	printk("\n");
+	pr_cont("\n");
 
 #define DO_TESTCASE_1B(desc, name, nr)				\
 	print_testname(desc"/"#nr);				\
 	dotest(name##_##nr, FAILURE, LOCKTYPE_RWLOCK);		\
-	printk("\n");
+	pr_cont("\n");
 
 #define DO_TESTCASE_3(desc, name, nr)				\
 	print_testname(desc"/"#nr);				\
 	dotest(name##_spin_##nr, FAILURE, LOCKTYPE_SPIN);	\
 	dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK);	\
 	dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK);	\
-	printk("\n");
+	pr_cont("\n");
 
 #define DO_TESTCASE_3RW(desc, name, nr)				\
 	print_testname(desc"/"#nr);				\
 	dotest(name##_spin_##nr, FAILURE, LOCKTYPE_SPIN|LOCKTYPE_RWLOCK);\
 	dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK);	\
 	dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK);	\
-	printk("\n");
+	pr_cont("\n");
 
 #define DO_TESTCASE_6(desc, name)				\
 	print_testname(desc);					\
@@ -1050,7 +1050,7 @@ static inline void print_testname(const
 	dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX);		\
 	dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM);		\
 	dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM);		\
-	printk("\n");
+	pr_cont("\n");
 
 #define DO_TESTCASE_6_SUCCESS(desc, name)			\
 	print_testname(desc);					\
@@ -1060,7 +1060,7 @@ static inline void print_testname(const
 	dotest(name##_mutex, SUCCESS, LOCKTYPE_MUTEX);		\
 	dotest(name##_wsem, SUCCESS, LOCKTYPE_RWSEM);		\
 	dotest(name##_rsem, SUCCESS, LOCKTYPE_RWSEM);		\
-	printk("\n");
+	pr_cont("\n");
 
 /*
  * 'read' variant: rlocks must not trigger.
@@ -1073,7 +1073,7 @@ static inline void print_testname(const
 	dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX);		\
 	dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM);		\
 	dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM);		\
-	printk("\n");
+	pr_cont("\n");
 
 #define DO_TESTCASE_2I(desc, name, nr)				\
 	DO_TESTCASE_1("hard-"desc, name##_hard, nr);		\
@@ -1726,25 +1726,25 @@ static void ww_tests(void)
 	dotest(ww_test_fail_acquire, SUCCESS, LOCKTYPE_WW);
 	dotest(ww_test_normal, SUCCESS, LOCKTYPE_WW);
 	dotest(ww_test_unneeded_slow, FAILURE, LOCKTYPE_WW);
-	printk("\n");
+	pr_cont("\n");
 
 	print_testname("ww contexts mixing");
 	dotest(ww_test_two_contexts, FAILURE, LOCKTYPE_WW);
 	dotest(ww_test_diff_class, FAILURE, LOCKTYPE_WW);
-	printk("\n");
+	pr_cont("\n");
 
 	print_testname("finishing ww context");
 	dotest(ww_test_context_done_twice, FAILURE, LOCKTYPE_WW);
 	dotest(ww_test_context_unlock_twice, FAILURE, LOCKTYPE_WW);
 	dotest(ww_test_context_fini_early, FAILURE, LOCKTYPE_WW);
 	dotest(ww_test_context_lock_after_done, FAILURE, LOCKTYPE_WW);
-	printk("\n");
+	pr_cont("\n");
 
 	print_testname("locking mismatches");
 	dotest(ww_test_object_unlock_twice, FAILURE, LOCKTYPE_WW);
 	dotest(ww_test_object_lock_unbalanced, FAILURE, LOCKTYPE_WW);
 	dotest(ww_test_object_lock_stale_context, FAILURE, LOCKTYPE_WW);
-	printk("\n");
+	pr_cont("\n");
 
 	print_testname("EDEADLK handling");
 	dotest(ww_test_edeadlk_normal, SUCCESS, LOCKTYPE_WW);
@@ -1757,11 +1757,11 @@ static void ww_tests(void)
 	dotest(ww_test_edeadlk_acquire_more_edeadlk_slow, FAILURE, LOCKTYPE_WW);
 	dotest(ww_test_edeadlk_acquire_wrong, FAILURE, LOCKTYPE_WW);
 	dotest(ww_test_edeadlk_acquire_wrong_slow, FAILURE, LOCKTYPE_WW);
-	printk("\n");
+	pr_cont("\n");
 
 	print_testname("spinlock nest unlocked");
 	dotest(ww_test_spin_nest_unlocked, FAILURE, LOCKTYPE_WW);
-	printk("\n");
+	pr_cont("\n");
 
 	printk("  -----------------------------------------------------\n");
 	printk("                                 |block | try  |context|\n");
@@ -1771,25 +1771,25 @@ static void ww_tests(void)
 	dotest(ww_test_context_block, FAILURE, LOCKTYPE_WW);
 	dotest(ww_test_context_try, SUCCESS, LOCKTYPE_WW);
 	dotest(ww_test_context_context, SUCCESS, LOCKTYPE_WW);
-	printk("\n");
+	pr_cont("\n");
 
 	print_testname("try");
 	dotest(ww_test_try_block, FAILURE, LOCKTYPE_WW);
 	dotest(ww_test_try_try, SUCCESS, LOCKTYPE_WW);
 	dotest(ww_test_try_context, FAILURE, LOCKTYPE_WW);
-	printk("\n");
+	pr_cont("\n");
 
 	print_testname("block");
 	dotest(ww_test_block_block, FAILURE, LOCKTYPE_WW);
 	dotest(ww_test_block_try, SUCCESS, LOCKTYPE_WW);
 	dotest(ww_test_block_context, FAILURE, LOCKTYPE_WW);
-	printk("\n");
+	pr_cont("\n");
 
 	print_testname("spinlock");
 	dotest(ww_test_spin_block, FAILURE, LOCKTYPE_WW);
 	dotest(ww_test_spin_try, SUCCESS, LOCKTYPE_WW);
 	dotest(ww_test_spin_context, FAILURE, LOCKTYPE_WW);
-	printk("\n");
+	pr_cont("\n");
 }
 
 void locking_selftest(void)
@@ -1829,32 +1829,32 @@ void locking_selftest(void)
 
 	printk("  --------------------------------------------------------------------------\n");
 	print_testname("recursive read-lock");
-	printk("             |");
+	pr_cont("             |");
 	dotest(rlock_AA1, SUCCESS, LOCKTYPE_RWLOCK);
-	printk("             |");
+	pr_cont("             |");
 	dotest(rsem_AA1, FAILURE, LOCKTYPE_RWSEM);
-	printk("\n");
+	pr_cont("\n");
 
 	print_testname("recursive read-lock #2");
-	printk("             |");
+	pr_cont("             |");
 	dotest(rlock_AA1B, SUCCESS, LOCKTYPE_RWLOCK);
-	printk("             |");
+	pr_cont("             |");
 	dotest(rsem_AA1B, FAILURE, LOCKTYPE_RWSEM);
-	printk("\n");
+	pr_cont("\n");
 
 	print_testname("mixed read-write-lock");
-	printk("             |");
+	pr_cont("             |");
 	dotest(rlock_AA2, FAILURE, LOCKTYPE_RWLOCK);
-	printk("             |");
+	pr_cont("             |");
 	dotest(rsem_AA2, FAILURE, LOCKTYPE_RWSEM);
-	printk("\n");
+	pr_cont("\n");
 
 	print_testname("mixed write-read-lock");
-	printk("             |");
+	pr_cont("             |");
 	dotest(rlock_AA3, FAILURE, LOCKTYPE_RWLOCK);
-	printk("             |");
+	pr_cont("             |");
 	dotest(rsem_AA3, FAILURE, LOCKTYPE_RWSEM);
-	printk("\n");
+	pr_cont("\n");
 
 	printk("  --------------------------------------------------------------------------\n");
 
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/Makefile linux-libre-4.9-gnu/Makefile
--- linux-libre-4.9-rc8-gnu/Makefile	2016-12-04 17:34:26.000000000 -0500
+++ linux-libre-4.9-gnu/Makefile	2016-12-11 17:39:18.000000000 -0500
@@ -1,8 +1,8 @@
 VERSION = 4
 PATCHLEVEL = 9
 SUBLEVEL = 0
-EXTRAVERSION = -rc8-gnu
-NAME = Psychotic Stoned Sheep
+EXTRAVERSION = -gnu
+NAME = Roaring Lionus
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/mm/shmem.c linux-libre-4.9-gnu/mm/shmem.c
--- linux-libre-4.9-rc8-gnu/mm/shmem.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/mm/shmem.c	2016-12-11 14:17:54.000000000 -0500
@@ -1848,6 +1848,18 @@ unlock:
 	return error;
 }
 
+/*
+ * This is like autoremove_wake_function, but it removes the wait queue
+ * entry unconditionally - even if something else had already woken the
+ * target.
+ */
+static int synchronous_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key)
+{
+	int ret = default_wake_function(wait, mode, sync, key);
+	list_del_init(&wait->task_list);
+	return ret;
+}
+
 static int shmem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 {
 	struct inode *inode = file_inode(vma->vm_file);
@@ -1883,7 +1895,7 @@ static int shmem_fault(struct vm_area_st
 		    vmf->pgoff >= shmem_falloc->start &&
 		    vmf->pgoff < shmem_falloc->next) {
 			wait_queue_head_t *shmem_falloc_waitq;
-			DEFINE_WAIT(shmem_fault_wait);
+			DEFINE_WAIT_FUNC(shmem_fault_wait, synchronous_wake_function);
 
 			ret = VM_FAULT_NOPAGE;
 			if ((vmf->flags & FAULT_FLAG_ALLOW_RETRY) &&
@@ -2665,6 +2677,7 @@ static long shmem_fallocate(struct file
 		spin_lock(&inode->i_lock);
 		inode->i_private = NULL;
 		wake_up_all(&shmem_falloc_waitq);
+		WARN_ON_ONCE(!list_empty(&shmem_falloc_waitq.task_list));
 		spin_unlock(&inode->i_lock);
 		error = 0;
 		goto out;
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/net/batman-adv/translation-table.c linux-libre-4.9-gnu/net/batman-adv/translation-table.c
--- linux-libre-4.9-rc8-gnu/net/batman-adv/translation-table.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/net/batman-adv/translation-table.c	2016-12-11 14:17:54.000000000 -0500
@@ -3282,7 +3282,7 @@ static bool batadv_send_my_tt_response(s
 							     &tvlv_tt_data,
 							     &tt_change,
 							     &tt_len);
-		if (!tt_len)
+		if (!tt_len || !tvlv_len)
 			goto unlock;
 
 		/* Copy the last orig_node's OGM buffer */
@@ -3300,7 +3300,7 @@ static bool batadv_send_my_tt_response(s
 							     &tvlv_tt_data,
 							     &tt_change,
 							     &tt_len);
-		if (!tt_len)
+		if (!tt_len || !tvlv_len)
 			goto out;
 
 		/* fill the rest of the tvlv with the real TT entries */
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/net/bridge/br_sysfs_br.c linux-libre-4.9-gnu/net/bridge/br_sysfs_br.c
--- linux-libre-4.9-rc8-gnu/net/bridge/br_sysfs_br.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/net/bridge/br_sysfs_br.c	2016-12-11 14:17:54.000000000 -0500
@@ -898,6 +898,7 @@ int br_sysfs_addbr(struct net_device *de
 	if (!br->ifobj) {
 		pr_info("%s: can't add kobject (directory) %s/%s\n",
 			__func__, dev->name, SYSFS_BRIDGE_PORT_SUBDIR);
+		err = -ENOMEM;
 		goto out3;
 	}
 	return 0;
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/net/caif/caif_socket.c linux-libre-4.9-gnu/net/caif/caif_socket.c
--- linux-libre-4.9-rc8-gnu/net/caif/caif_socket.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/net/caif/caif_socket.c	2016-12-11 14:17:54.000000000 -0500
@@ -1107,10 +1107,7 @@ static struct net_proto_family caif_fami
 
 static int __init caif_sktinit_module(void)
 {
-	int err = sock_register(&caif_family_ops);
-	if (!err)
-		return err;
-	return 0;
+	return sock_register(&caif_family_ops);
 }
 
 static void __exit caif_sktexit_module(void)
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/net/can/raw.c linux-libre-4.9-gnu/net/can/raw.c
--- linux-libre-4.9-rc8-gnu/net/can/raw.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/net/can/raw.c	2016-12-11 14:17:54.000000000 -0500
@@ -499,6 +499,9 @@ static int raw_setsockopt(struct socket
 		if (optlen % sizeof(struct can_filter) != 0)
 			return -EINVAL;
 
+		if (optlen > CAN_RAW_FILTER_MAX * sizeof(struct can_filter))
+			return -EINVAL;
+
 		count = optlen / sizeof(struct can_filter);
 
 		if (count > 1) {
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/net/dcb/dcbnl.c linux-libre-4.9-gnu/net/dcb/dcbnl.c
--- linux-libre-4.9-rc8-gnu/net/dcb/dcbnl.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/net/dcb/dcbnl.c	2016-12-11 14:17:54.000000000 -0500
@@ -1353,6 +1353,7 @@ static int dcbnl_cee_fill(struct sk_buff
 dcb_unlock:
 	spin_unlock_bh(&dcb_lock);
 nla_put_failure:
+	err = -EMSGSIZE;
 	return err;
 }
 
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/net/ipv4/fib_trie.c linux-libre-4.9-gnu/net/ipv4/fib_trie.c
--- linux-libre-4.9-rc8-gnu/net/ipv4/fib_trie.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/net/ipv4/fib_trie.c	2016-12-11 14:17:54.000000000 -0500
@@ -719,6 +719,13 @@ static unsigned char update_suffix(struc
 {
 	unsigned char slen = tn->pos;
 	unsigned long stride, i;
+	unsigned char slen_max;
+
+	/* only vector 0 can have a suffix length greater than or equal to
+	 * tn->pos + tn->bits, the second highest node will have a suffix
+	 * length at most of tn->pos + tn->bits - 1
+	 */
+	slen_max = min_t(unsigned char, tn->pos + tn->bits - 1, tn->slen);
 
 	/* search though the list of children looking for nodes that might
 	 * have a suffix greater than the one we currently have.  This is
@@ -736,12 +743,8 @@ static unsigned char update_suffix(struc
 		slen = n->slen;
 		i &= ~(stride - 1);
 
-		/* if slen covers all but the last bit we can stop here
-		 * there will be nothing longer than that since only node
-		 * 0 and 1 << (bits - 1) could have that as their suffix
-		 * length.
-		 */
-		if ((slen + 1) >= (tn->pos + tn->bits))
+		/* stop searching if we have hit the maximum possible value */
+		if (slen >= slen_max)
 			break;
 	}
 
@@ -913,39 +916,27 @@ static struct key_vector *resize(struct
 		return collapse(t, tn);
 
 	/* update parent in case halve failed */
-	tp = node_parent(tn);
-
-	/* Return if at least one deflate was run */
-	if (max_work != MAX_WORK)
-		return tp;
-
-	/* push the suffix length to the parent node */
-	if (tn->slen > tn->pos) {
-		unsigned char slen = update_suffix(tn);
-
-		if (slen > tp->slen)
-			tp->slen = slen;
-	}
-
-	return tp;
+	return node_parent(tn);
 }
 
-static void leaf_pull_suffix(struct key_vector *tp, struct key_vector *l)
+static void node_pull_suffix(struct key_vector *tn, unsigned char slen)
 {
-	while ((tp->slen > tp->pos) && (tp->slen > l->slen)) {
-		if (update_suffix(tp) > l->slen)
+	unsigned char node_slen = tn->slen;
+
+	while ((node_slen > tn->pos) && (node_slen > slen)) {
+		slen = update_suffix(tn);
+		if (node_slen == slen)
 			break;
-		tp = node_parent(tp);
+
+		tn = node_parent(tn);
+		node_slen = tn->slen;
 	}
 }
 
-static void leaf_push_suffix(struct key_vector *tn, struct key_vector *l)
+static void node_push_suffix(struct key_vector *tn, unsigned char slen)
 {
-	/* if this is a new leaf then tn will be NULL and we can sort
-	 * out parent suffix lengths as a part of trie_rebalance
-	 */
-	while (tn->slen < l->slen) {
-		tn->slen = l->slen;
+	while (tn->slen < slen) {
+		tn->slen = slen;
 		tn = node_parent(tn);
 	}
 }
@@ -1066,6 +1057,7 @@ static int fib_insert_node(struct trie *
 	}
 
 	/* Case 3: n is NULL, and will just insert a new leaf */
+	node_push_suffix(tp, new->fa_slen);
 	NODE_INIT_PARENT(l, tp);
 	put_child_root(tp, key, l);
 	trie_rebalance(t, tp);
@@ -1107,7 +1099,7 @@ static int fib_insert_alias(struct trie
 	/* if we added to the tail node then we need to update slen */
 	if (l->slen < new->fa_slen) {
 		l->slen = new->fa_slen;
-		leaf_push_suffix(tp, l);
+		node_push_suffix(tp, new->fa_slen);
 	}
 
 	return 0;
@@ -1499,6 +1491,8 @@ static void fib_remove_alias(struct trie
 	 * out parent suffix lengths as a part of trie_rebalance
 	 */
 	if (hlist_empty(&l->leaf)) {
+		if (tp->slen == l->slen)
+			node_pull_suffix(tp, tp->pos);
 		put_child_root(tp, l->key, NULL);
 		node_free(l);
 		trie_rebalance(t, tp);
@@ -1511,7 +1505,7 @@ static void fib_remove_alias(struct trie
 
 	/* update the trie with the latest suffix length */
 	l->slen = fa->fa_slen;
-	leaf_pull_suffix(tp, l);
+	node_pull_suffix(tp, fa->fa_slen);
 }
 
 /* Caller must hold RTNL. */
@@ -1783,6 +1777,10 @@ void fib_table_flush_external(struct fib
 			if (IS_TRIE(pn))
 				break;
 
+			/* update the suffix to address pulled leaves */
+			if (pn->slen > pn->pos)
+				update_suffix(pn);
+
 			/* resize completed node */
 			pn = resize(t, pn);
 			cindex = get_index(pkey, pn);
@@ -1849,6 +1847,10 @@ int fib_table_flush(struct net *net, str
 			if (IS_TRIE(pn))
 				break;
 
+			/* update the suffix to address pulled leaves */
+			if (pn->slen > pn->pos)
+				update_suffix(pn);
+
 			/* resize completed node */
 			pn = resize(t, pn);
 			cindex = get_index(pkey, pn);
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/net/ipv4/ping.c linux-libre-4.9-gnu/net/ipv4/ping.c
--- linux-libre-4.9-rc8-gnu/net/ipv4/ping.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/net/ipv4/ping.c	2016-12-11 14:17:54.000000000 -0500
@@ -657,6 +657,10 @@ int ping_common_sendmsg(int family, stru
 	if (len > 0xFFFF)
 		return -EMSGSIZE;
 
+	/* Must have at least a full ICMP header. */
+	if (len < icmph_len)
+		return -EINVAL;
+
 	/*
 	 *	Check the flags.
 	 */
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/net/ipv4/tcp_input.c linux-libre-4.9-gnu/net/ipv4/tcp_input.c
--- linux-libre-4.9-rc8-gnu/net/ipv4/tcp_input.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/net/ipv4/tcp_input.c	2016-12-11 14:17:54.000000000 -0500
@@ -128,6 +128,23 @@ int sysctl_tcp_invalid_ratelimit __read_
 #define REXMIT_LOST	1 /* retransmit packets marked lost */
 #define REXMIT_NEW	2 /* FRTO-style transmit of unsent/new packets */
 
+static void tcp_gro_dev_warn(struct sock *sk, const struct sk_buff *skb)
+{
+	static bool __once __read_mostly;
+
+	if (!__once) {
+		struct net_device *dev;
+
+		__once = true;
+
+		rcu_read_lock();
+		dev = dev_get_by_index_rcu(sock_net(sk), skb->skb_iif);
+		pr_warn("%s: Driver has suspect GRO implementation, TCP performance may be compromised.\n",
+			dev ? dev->name : "Unknown driver");
+		rcu_read_unlock();
+	}
+}
+
 /* Adapt the MSS value used to make delayed ack decision to the
  * real world.
  */
@@ -144,7 +161,10 @@ static void tcp_measure_rcv_mss(struct s
 	 */
 	len = skb_shinfo(skb)->gso_size ? : skb->len;
 	if (len >= icsk->icsk_ack.rcv_mss) {
-		icsk->icsk_ack.rcv_mss = len;
+		icsk->icsk_ack.rcv_mss = min_t(unsigned int, len,
+					       tcp_sk(sk)->advmss);
+		if (unlikely(icsk->icsk_ack.rcv_mss != len))
+			tcp_gro_dev_warn(sk, skb);
 	} else {
 		/* Otherwise, we make more careful check taking into account,
 		 * that SACKs block is variable.
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/net/mpls/af_mpls.c linux-libre-4.9-gnu/net/mpls/af_mpls.c
--- linux-libre-4.9-rc8-gnu/net/mpls/af_mpls.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/net/mpls/af_mpls.c	2016-12-11 14:17:54.000000000 -0500
@@ -1252,7 +1252,7 @@ static int rtm_to_route_config(struct sk
 		if (!nla)
 			continue;
 
-		switch(index) {
+		switch (index) {
 		case RTA_OIF:
 			cfg->rc_ifindex = nla_get_u32(nla);
 			break;
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/net/netlink/af_netlink.c linux-libre-4.9-gnu/net/netlink/af_netlink.c
--- linux-libre-4.9-rc8-gnu/net/netlink/af_netlink.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/net/netlink/af_netlink.c	2016-12-11 14:17:54.000000000 -0500
@@ -322,11 +322,13 @@ static void netlink_skb_set_owner_r(stru
 	sk_mem_charge(sk, skb->truesize);
 }
 
-static void __netlink_sock_destruct(struct sock *sk)
+static void netlink_sock_destruct(struct sock *sk)
 {
 	struct netlink_sock *nlk = nlk_sk(sk);
 
 	if (nlk->cb_running) {
+		if (nlk->cb.done)
+			nlk->cb.done(&nlk->cb);
 		module_put(nlk->cb.module);
 		kfree_skb(nlk->cb.skb);
 	}
@@ -348,21 +350,7 @@ static void netlink_sock_destruct_work(s
 	struct netlink_sock *nlk = container_of(work, struct netlink_sock,
 						work);
 
-	nlk->cb.done(&nlk->cb);
-	__netlink_sock_destruct(&nlk->sk);
-}
-
-static void netlink_sock_destruct(struct sock *sk)
-{
-	struct netlink_sock *nlk = nlk_sk(sk);
-
-	if (nlk->cb_running && nlk->cb.done) {
-		INIT_WORK(&nlk->work, netlink_sock_destruct_work);
-		schedule_work(&nlk->work);
-		return;
-	}
-
-	__netlink_sock_destruct(sk);
+	sk_free(&nlk->sk);
 }
 
 /* This lock without WQ_FLAG_EXCLUSIVE is good on UP and it is _very_ bad on
@@ -667,8 +655,18 @@ out_module:
 static void deferred_put_nlk_sk(struct rcu_head *head)
 {
 	struct netlink_sock *nlk = container_of(head, struct netlink_sock, rcu);
+	struct sock *sk = &nlk->sk;
 
-	sock_put(&nlk->sk);
+	if (!atomic_dec_and_test(&sk->sk_refcnt))
+		return;
+
+	if (nlk->cb_running && nlk->cb.done) {
+		INIT_WORK(&nlk->work, netlink_sock_destruct_work);
+		schedule_work(&nlk->work);
+		return;
+	}
+
+	sk_free(sk);
 }
 
 static int netlink_release(struct socket *sock)
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/sound/sparc/dbri.c linux-libre-4.9-gnu/sound/sparc/dbri.c
--- linux-libre-4.9-rc8-gnu/sound/sparc/dbri.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/sound/sparc/dbri.c	2016-12-11 14:17:54.000000000 -0500
@@ -1702,7 +1702,7 @@ interrupts are disabled.
 static void xmit_descs(struct snd_dbri *dbri)
 {
 	struct dbri_streaminfo *info;
-	u32 dvma_addr = (u32)dbri->dma_dvma;
+	u32 dvma_addr;
 	s32 *cmd;
 	unsigned long flags;
 	int first_td;
@@ -1710,6 +1710,7 @@ static void xmit_descs(struct snd_dbri *
 	if (dbri == NULL)
 		return;		/* Disabled */
 
+	dvma_addr = (u32)dbri->dma_dvma;
 	info = &dbri->stream_info[DBRI_REC];
 	spin_lock_irqsave(&dbri->lock, flags);
 
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/tools/objtool/arch/x86/decode.c linux-libre-4.9-gnu/tools/objtool/arch/x86/decode.c
--- linux-libre-4.9-rc8-gnu/tools/objtool/arch/x86/decode.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/tools/objtool/arch/x86/decode.c	2016-12-11 14:17:54.000000000 -0500
@@ -99,7 +99,7 @@ int arch_decode_instruction(struct elf *
 		break;
 
 	case 0x8d:
-		if (insn.rex_prefix.bytes &&
+		if (insn.rex_prefix.nbytes &&
 		    insn.rex_prefix.bytes[0] == 0x48 &&
 		    insn.modrm.nbytes && insn.modrm.bytes[0] == 0x2c &&
 		    insn.sib.nbytes && insn.sib.bytes[0] == 0x24)
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/tools/testing/nvdimm/Kbuild linux-libre-4.9-gnu/tools/testing/nvdimm/Kbuild
--- linux-libre-4.9-rc8-gnu/tools/testing/nvdimm/Kbuild	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/tools/testing/nvdimm/Kbuild	2016-12-11 14:17:54.000000000 -0500
@@ -14,6 +14,7 @@ ldflags-y += --wrap=devm_memremap_pages
 ldflags-y += --wrap=insert_resource
 ldflags-y += --wrap=remove_resource
 ldflags-y += --wrap=acpi_evaluate_object
+ldflags-y += --wrap=acpi_evaluate_dsm
 
 DRIVERS := ../../../drivers
 NVDIMM_SRC := $(DRIVERS)/nvdimm
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/tools/testing/nvdimm/test/iomap.c linux-libre-4.9-gnu/tools/testing/nvdimm/test/iomap.c
--- linux-libre-4.9-rc8-gnu/tools/testing/nvdimm/test/iomap.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/tools/testing/nvdimm/test/iomap.c	2016-12-11 14:17:54.000000000 -0500
@@ -26,14 +26,17 @@ static LIST_HEAD(iomap_head);
 
 static struct iomap_ops {
 	nfit_test_lookup_fn nfit_test_lookup;
+	nfit_test_evaluate_dsm_fn evaluate_dsm;
 	struct list_head list;
 } iomap_ops = {
 	.list = LIST_HEAD_INIT(iomap_ops.list),
 };
 
-void nfit_test_setup(nfit_test_lookup_fn lookup)
+void nfit_test_setup(nfit_test_lookup_fn lookup,
+		nfit_test_evaluate_dsm_fn evaluate)
 {
 	iomap_ops.nfit_test_lookup = lookup;
+	iomap_ops.evaluate_dsm = evaluate;
 	list_add_rcu(&iomap_ops.list, &iomap_head);
 }
 EXPORT_SYMBOL(nfit_test_setup);
@@ -367,4 +370,22 @@ acpi_status __wrap_acpi_evaluate_object(
 }
 EXPORT_SYMBOL(__wrap_acpi_evaluate_object);
 
+union acpi_object * __wrap_acpi_evaluate_dsm(acpi_handle handle, const u8 *uuid,
+		u64 rev, u64 func, union acpi_object *argv4)
+{
+	union acpi_object *obj = ERR_PTR(-ENXIO);
+	struct iomap_ops *ops;
+
+	rcu_read_lock();
+	ops = list_first_or_null_rcu(&iomap_head, typeof(*ops), list);
+	if (ops)
+		obj = ops->evaluate_dsm(handle, uuid, rev, func, argv4);
+	rcu_read_unlock();
+
+	if (IS_ERR(obj))
+		return acpi_evaluate_dsm(handle, uuid, rev, func, argv4);
+	return obj;
+}
+EXPORT_SYMBOL(__wrap_acpi_evaluate_dsm);
+
 MODULE_LICENSE("GPL v2");
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/tools/testing/nvdimm/test/nfit.c linux-libre-4.9-gnu/tools/testing/nvdimm/test/nfit.c
--- linux-libre-4.9-rc8-gnu/tools/testing/nvdimm/test/nfit.c	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/tools/testing/nvdimm/test/nfit.c	2016-12-11 14:17:54.000000000 -0500
@@ -23,6 +23,7 @@
 #include <linux/sizes.h>
 #include <linux/list.h>
 #include <linux/slab.h>
+#include <nd-core.h>
 #include <nfit.h>
 #include <nd.h>
 #include "nfit_test.h"
@@ -1506,6 +1507,225 @@ static int nfit_test_blk_do_io(struct nd
 	return 0;
 }
 
+static unsigned long nfit_ctl_handle;
+
+union acpi_object *result;
+
+static union acpi_object *nfit_test_evaluate_dsm(acpi_handle handle,
+		const u8 *uuid, u64 rev, u64 func, union acpi_object *argv4)
+{
+	if (handle != &nfit_ctl_handle)
+		return ERR_PTR(-ENXIO);
+
+	return result;
+}
+
+static int setup_result(void *buf, size_t size)
+{
+	result = kmalloc(sizeof(union acpi_object) + size, GFP_KERNEL);
+	if (!result)
+		return -ENOMEM;
+	result->package.type = ACPI_TYPE_BUFFER,
+	result->buffer.pointer = (void *) (result + 1);
+	result->buffer.length = size;
+	memcpy(result->buffer.pointer, buf, size);
+	memset(buf, 0, size);
+	return 0;
+}
+
+static int nfit_ctl_test(struct device *dev)
+{
+	int rc, cmd_rc;
+	struct nvdimm *nvdimm;
+	struct acpi_device *adev;
+	struct nfit_mem *nfit_mem;
+	struct nd_ars_record *record;
+	struct acpi_nfit_desc *acpi_desc;
+	const u64 test_val = 0x0123456789abcdefULL;
+	unsigned long mask, cmd_size, offset;
+	union {
+		struct nd_cmd_get_config_size cfg_size;
+		struct nd_cmd_ars_status ars_stat;
+		struct nd_cmd_ars_cap ars_cap;
+		char buf[sizeof(struct nd_cmd_ars_status)
+			+ sizeof(struct nd_ars_record)];
+	} cmds;
+
+	adev = devm_kzalloc(dev, sizeof(*adev), GFP_KERNEL);
+	if (!adev)
+		return -ENOMEM;
+	*adev = (struct acpi_device) {
+		.handle = &nfit_ctl_handle,
+		.dev = {
+			.init_name = "test-adev",
+		},
+	};
+
+	acpi_desc = devm_kzalloc(dev, sizeof(*acpi_desc), GFP_KERNEL);
+	if (!acpi_desc)
+		return -ENOMEM;
+	*acpi_desc = (struct acpi_nfit_desc) {
+		.nd_desc = {
+			.cmd_mask = 1UL << ND_CMD_ARS_CAP
+				| 1UL << ND_CMD_ARS_START
+				| 1UL << ND_CMD_ARS_STATUS
+				| 1UL << ND_CMD_CLEAR_ERROR,
+			.module = THIS_MODULE,
+			.provider_name = "ACPI.NFIT",
+			.ndctl = acpi_nfit_ctl,
+		},
+		.dev = &adev->dev,
+	};
+
+	nfit_mem = devm_kzalloc(dev, sizeof(*nfit_mem), GFP_KERNEL);
+	if (!nfit_mem)
+		return -ENOMEM;
+
+	mask = 1UL << ND_CMD_SMART | 1UL << ND_CMD_SMART_THRESHOLD
+		| 1UL << ND_CMD_DIMM_FLAGS | 1UL << ND_CMD_GET_CONFIG_SIZE
+		| 1UL << ND_CMD_GET_CONFIG_DATA | 1UL << ND_CMD_SET_CONFIG_DATA
+		| 1UL << ND_CMD_VENDOR;
+	*nfit_mem = (struct nfit_mem) {
+		.adev = adev,
+		.family = NVDIMM_FAMILY_INTEL,
+		.dsm_mask = mask,
+	};
+
+	nvdimm = devm_kzalloc(dev, sizeof(*nvdimm), GFP_KERNEL);
+	if (!nvdimm)
+		return -ENOMEM;
+	*nvdimm = (struct nvdimm) {
+		.provider_data = nfit_mem,
+		.cmd_mask = mask,
+		.dev = {
+			.init_name = "test-dimm",
+		},
+	};
+
+
+	/* basic checkout of a typical 'get config size' command */
+	cmd_size = sizeof(cmds.cfg_size);
+	cmds.cfg_size = (struct nd_cmd_get_config_size) {
+		.status = 0,
+		.config_size = SZ_128K,
+		.max_xfer = SZ_4K,
+	};
+	rc = setup_result(cmds.buf, cmd_size);
+	if (rc)
+		return rc;
+	rc = acpi_nfit_ctl(&acpi_desc->nd_desc, nvdimm, ND_CMD_GET_CONFIG_SIZE,
+			cmds.buf, cmd_size, &cmd_rc);
+
+	if (rc < 0 || cmd_rc || cmds.cfg_size.status != 0
+			|| cmds.cfg_size.config_size != SZ_128K
+			|| cmds.cfg_size.max_xfer != SZ_4K) {
+		dev_dbg(dev, "%s: failed at: %d rc: %d cmd_rc: %d\n",
+				__func__, __LINE__, rc, cmd_rc);
+		return -EIO;
+	}
+
+
+	/* test ars_status with zero output */
+	cmd_size = offsetof(struct nd_cmd_ars_status, address);
+	cmds.ars_stat = (struct nd_cmd_ars_status) {
+		.out_length = 0,
+	};
+	rc = setup_result(cmds.buf, cmd_size);
+	if (rc)
+		return rc;
+	rc = acpi_nfit_ctl(&acpi_desc->nd_desc, NULL, ND_CMD_ARS_STATUS,
+			cmds.buf, cmd_size, &cmd_rc);
+
+	if (rc < 0 || cmd_rc) {
+		dev_dbg(dev, "%s: failed at: %d rc: %d cmd_rc: %d\n",
+				__func__, __LINE__, rc, cmd_rc);
+		return -EIO;
+	}
+
+
+	/* test ars_cap with benign extended status */
+	cmd_size = sizeof(cmds.ars_cap);
+	cmds.ars_cap = (struct nd_cmd_ars_cap) {
+		.status = ND_ARS_PERSISTENT << 16,
+	};
+	offset = offsetof(struct nd_cmd_ars_cap, status);
+	rc = setup_result(cmds.buf + offset, cmd_size - offset);
+	if (rc)
+		return rc;
+	rc = acpi_nfit_ctl(&acpi_desc->nd_desc, NULL, ND_CMD_ARS_CAP,
+			cmds.buf, cmd_size, &cmd_rc);
+
+	if (rc < 0 || cmd_rc) {
+		dev_dbg(dev, "%s: failed at: %d rc: %d cmd_rc: %d\n",
+				__func__, __LINE__, rc, cmd_rc);
+		return -EIO;
+	}
+
+
+	/* test ars_status with 'status' trimmed from 'out_length' */
+	cmd_size = sizeof(cmds.ars_stat) + sizeof(struct nd_ars_record);
+	cmds.ars_stat = (struct nd_cmd_ars_status) {
+		.out_length = cmd_size - 4,
+	};
+	record = &cmds.ars_stat.records[0];
+	*record = (struct nd_ars_record) {
+		.length = test_val,
+	};
+	rc = setup_result(cmds.buf, cmd_size);
+	if (rc)
+		return rc;
+	rc = acpi_nfit_ctl(&acpi_desc->nd_desc, NULL, ND_CMD_ARS_STATUS,
+			cmds.buf, cmd_size, &cmd_rc);
+
+	if (rc < 0 || cmd_rc || record->length != test_val) {
+		dev_dbg(dev, "%s: failed at: %d rc: %d cmd_rc: %d\n",
+				__func__, __LINE__, rc, cmd_rc);
+		return -EIO;
+	}
+
+
+	/* test ars_status with 'Output (Size)' including 'status' */
+	cmd_size = sizeof(cmds.ars_stat) + sizeof(struct nd_ars_record);
+	cmds.ars_stat = (struct nd_cmd_ars_status) {
+		.out_length = cmd_size,
+	};
+	record = &cmds.ars_stat.records[0];
+	*record = (struct nd_ars_record) {
+		.length = test_val,
+	};
+	rc = setup_result(cmds.buf, cmd_size);
+	if (rc)
+		return rc;
+	rc = acpi_nfit_ctl(&acpi_desc->nd_desc, NULL, ND_CMD_ARS_STATUS,
+			cmds.buf, cmd_size, &cmd_rc);
+
+	if (rc < 0 || cmd_rc || record->length != test_val) {
+		dev_dbg(dev, "%s: failed at: %d rc: %d cmd_rc: %d\n",
+				__func__, __LINE__, rc, cmd_rc);
+		return -EIO;
+	}
+
+
+	/* test extended status for get_config_size results in failure */
+	cmd_size = sizeof(cmds.cfg_size);
+	cmds.cfg_size = (struct nd_cmd_get_config_size) {
+		.status = 1 << 16,
+	};
+	rc = setup_result(cmds.buf, cmd_size);
+	if (rc)
+		return rc;
+	rc = acpi_nfit_ctl(&acpi_desc->nd_desc, nvdimm, ND_CMD_GET_CONFIG_SIZE,
+			cmds.buf, cmd_size, &cmd_rc);
+
+	if (rc < 0 || cmd_rc >= 0) {
+		dev_dbg(dev, "%s: failed at: %d rc: %d cmd_rc: %d\n",
+				__func__, __LINE__, rc, cmd_rc);
+		return -EIO;
+	}
+
+	return 0;
+}
+
 static int nfit_test_probe(struct platform_device *pdev)
 {
 	struct nvdimm_bus_descriptor *nd_desc;
@@ -1516,6 +1736,12 @@ static int nfit_test_probe(struct platfo
 	union acpi_object *obj;
 	int rc;
 
+	if (strcmp(dev_name(&pdev->dev), "nfit_test.0") == 0) {
+		rc = nfit_ctl_test(&pdev->dev);
+		if (rc)
+			return rc;
+	}
+
 	nfit_test = to_nfit_test(&pdev->dev);
 
 	/* common alloc */
@@ -1639,11 +1865,13 @@ static __init int nfit_test_init(void)
 {
 	int rc, i;
 
-	nfit_test_dimm = class_create(THIS_MODULE, "nfit_test_dimm");
-	if (IS_ERR(nfit_test_dimm))
-		return PTR_ERR(nfit_test_dimm);
+	nfit_test_setup(nfit_test_lookup, nfit_test_evaluate_dsm);
 
-	nfit_test_setup(nfit_test_lookup);
+	nfit_test_dimm = class_create(THIS_MODULE, "nfit_test_dimm");
+	if (IS_ERR(nfit_test_dimm)) {
+		rc = PTR_ERR(nfit_test_dimm);
+		goto err_register;
+	}
 
 	for (i = 0; i < NUM_NFITS; i++) {
 		struct nfit_test *nfit_test;
diff -druNp --no-dereference linux-libre-4.9-rc8-gnu/tools/testing/nvdimm/test/nfit_test.h linux-libre-4.9-gnu/tools/testing/nvdimm/test/nfit_test.h
--- linux-libre-4.9-rc8-gnu/tools/testing/nvdimm/test/nfit_test.h	2016-12-04 15:50:51.000000000 -0500
+++ linux-libre-4.9-gnu/tools/testing/nvdimm/test/nfit_test.h	2016-12-11 14:17:54.000000000 -0500
@@ -31,11 +31,17 @@ struct nfit_test_resource {
 	void *buf;
 };
 
+union acpi_object;
+typedef void *acpi_handle;
+
 typedef struct nfit_test_resource *(*nfit_test_lookup_fn)(resource_size_t);
+typedef union acpi_object *(*nfit_test_evaluate_dsm_fn)(acpi_handle handle,
+		const u8 *uuid, u64 rev, u64 func, union acpi_object *argv4);
 void __iomem *__wrap_ioremap_nocache(resource_size_t offset,
 		unsigned long size);
 void __wrap_iounmap(volatile void __iomem *addr);
-void nfit_test_setup(nfit_test_lookup_fn lookup);
+void nfit_test_setup(nfit_test_lookup_fn lookup,
+		nfit_test_evaluate_dsm_fn evaluate);
 void nfit_test_teardown(void);
 struct nfit_test_resource *get_nfit_res(resource_size_t resource);
 #endif
