diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/arm/boot/deflate_xip_data.sh linux-libre-4.16-gnu/arch/arm/boot/deflate_xip_data.sh
--- linux-libre-4.16-rc7-gnu/arch/arm/boot/deflate_xip_data.sh	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/arm/boot/deflate_xip_data.sh	2018-04-01 17:20:27.000000000 -0400
@@ -30,7 +30,7 @@ esac
 
 sym_val() {
 	# extract hex value for symbol in $1
-	local val=$($NM "$VMLINUX" | sed -n "/ $1$/{s/ .*$//p;q}")
+	local val=$($NM "$VMLINUX" 2>/dev/null | sed -n "/ $1\$/{s/ .*$//p;q}")
 	[ "$val" ] || { echo "can't find $1 in $VMLINUX" 1>&2; exit 1; }
 	# convert from hex to decimal
 	echo $((0x$val))
@@ -48,12 +48,12 @@ data_end=$(($_edata_loc - $base_offset))
 file_end=$(stat -c "%s" "$XIPIMAGE")
 if [ "$file_end" != "$data_end" ]; then
 	printf "end of xipImage doesn't match with _edata_loc (%#x vs %#x)\n" \
-	       $(($file_end + $base_offset)) $_edata_loc 2>&1
+	       $(($file_end + $base_offset)) $_edata_loc 1>&2
 	exit 1;
 fi
 
 # be ready to clean up
-trap 'rm -f "$XIPIMAGE.tmp"' 0 1 2 3
+trap 'rm -f "$XIPIMAGE.tmp"; exit 1' 1 2 3
 
 # substitute the data section by a compressed version
 $DD if="$XIPIMAGE" count=$data_start iflag=count_bytes of="$XIPIMAGE.tmp"
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/arm/boot/dts/aspeed-g4.dtsi linux-libre-4.16-gnu/arch/arm/boot/dts/aspeed-g4.dtsi
--- linux-libre-4.16-rc7-gnu/arch/arm/boot/dts/aspeed-g4.dtsi	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/arm/boot/dts/aspeed-g4.dtsi	2018-04-01 17:20:27.000000000 -0400
@@ -42,6 +42,11 @@
 		};
 	};
 
+	memory@40000000 {
+		device_type = "memory";
+		reg = <0x40000000 0>;
+	};
+
 	ahb {
 		compatible = "simple-bus";
 		#address-cells = <1>;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/arm/boot/dts/aspeed-g5.dtsi linux-libre-4.16-gnu/arch/arm/boot/dts/aspeed-g5.dtsi
--- linux-libre-4.16-rc7-gnu/arch/arm/boot/dts/aspeed-g5.dtsi	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/arm/boot/dts/aspeed-g5.dtsi	2018-04-01 17:20:27.000000000 -0400
@@ -42,6 +42,11 @@
 		};
 	};
 
+	memory@80000000 {
+		device_type = "memory";
+		reg = <0x80000000 0>;
+	};
+
 	ahb {
 		compatible = "simple-bus";
 		#address-cells = <1>;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/arm/boot/dts/imx7d-sdb.dts linux-libre-4.16-gnu/arch/arm/boot/dts/imx7d-sdb.dts
--- linux-libre-4.16-rc7-gnu/arch/arm/boot/dts/imx7d-sdb.dts	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/arm/boot/dts/imx7d-sdb.dts	2018-04-01 17:20:27.000000000 -0400
@@ -82,7 +82,7 @@
 		enable-active-high;
 	};
 
-	reg_usb_otg2_vbus: regulator-usb-otg1-vbus {
+	reg_usb_otg2_vbus: regulator-usb-otg2-vbus {
 		compatible = "regulator-fixed";
 		regulator-name = "usb_otg2_vbus";
 		regulator-min-microvolt = <5000000>;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/arm/boot/dts/rk3288.dtsi linux-libre-4.16-gnu/arch/arm/boot/dts/rk3288.dtsi
--- linux-libre-4.16-rc7-gnu/arch/arm/boot/dts/rk3288.dtsi	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/arm/boot/dts/rk3288.dtsi	2018-04-01 17:20:27.000000000 -0400
@@ -927,6 +927,7 @@
 	i2s: i2s@ff890000 {
 		compatible = "rockchip,rk3288-i2s", "rockchip,rk3066-i2s";
 		reg = <0x0 0xff890000 0x0 0x10000>;
+		#sound-dai-cells = <0>;
 		interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -1176,6 +1177,7 @@
 		compatible = "rockchip,rk3288-dw-hdmi";
 		reg = <0x0 0xff980000 0x0 0x20000>;
 		reg-io-width = <4>;
+		#sound-dai-cells = <0>;
 		rockchip,grf = <&grf>;
 		interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru  PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_HDCP>, <&cru SCLK_HDMI_CEC>;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts linux-libre-4.16-gnu/arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts
--- linux-libre-4.16-rc7-gnu/arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts	2018-04-01 17:20:27.000000000 -0400
@@ -42,7 +42,6 @@
 
 /dts-v1/;
 #include "sun6i-a31s.dtsi"
-#include "sunxi-common-regulators.dtsi"
 #include <dt-bindings/gpio/gpio.h>
 
 / {
@@ -99,6 +98,7 @@
 	pinctrl-0 = <&gmac_pins_rgmii_a>, <&gmac_phy_reset_pin_bpi_m2>;
 	phy = <&phy1>;
 	phy-mode = "rgmii";
+	phy-supply = <&reg_dldo1>;
 	snps,reset-gpio = <&pio 0 21 GPIO_ACTIVE_HIGH>; /* PA21 */
 	snps,reset-active-low;
 	snps,reset-delays-us = <0 10000 30000>;
@@ -118,7 +118,7 @@
 &mmc0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_bpi_m2>;
-	vmmc-supply = <&reg_vcc3v0>;
+	vmmc-supply = <&reg_dcdc1>;
 	bus-width = <4>;
 	cd-gpios = <&pio 0 4 GPIO_ACTIVE_HIGH>; /* PA4 */
 	cd-inverted;
@@ -132,7 +132,7 @@
 &mmc2 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&mmc2_pins_a>;
-	vmmc-supply = <&reg_vcc3v0>;
+	vmmc-supply = <&reg_aldo1>;
 	mmc-pwrseq = <&mmc2_pwrseq>;
 	bus-width = <4>;
 	non-removable;
@@ -163,6 +163,8 @@
 		reg = <0x68>;
 		interrupt-parent = <&nmi_intc>;
 		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+		eldoin-supply = <&reg_dcdc1>;
+		x-powers,drive-vbus-en;
 	};
 };
 
@@ -193,7 +195,28 @@
 
 #include "axp22x.dtsi"
 
+&reg_aldo1 {
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+	regulator-name = "vcc-wifi";
+};
+
+&reg_aldo2 {
+	regulator-always-on;
+	regulator-min-microvolt = <2500000>;
+	regulator-max-microvolt = <2500000>;
+	regulator-name = "vcc-gmac";
+};
+
+&reg_aldo3 {
+	regulator-always-on;
+	regulator-min-microvolt = <3000000>;
+	regulator-max-microvolt = <3000000>;
+	regulator-name = "avcc";
+};
+
 &reg_dc5ldo {
+	regulator-always-on;
 	regulator-min-microvolt = <700000>;
 	regulator-max-microvolt = <1320000>;
 	regulator-name = "vdd-cpus";
@@ -233,6 +256,40 @@
 	regulator-name = "vcc-dram";
 };
 
+&reg_dldo1 {
+	regulator-min-microvolt = <3000000>;
+	regulator-max-microvolt = <3000000>;
+	regulator-name = "vcc-mac";
+};
+
+&reg_dldo2 {
+	regulator-min-microvolt = <2800000>;
+	regulator-max-microvolt = <2800000>;
+	regulator-name = "avdd-csi";
+};
+
+&reg_dldo3 {
+	regulator-always-on;
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+	regulator-name = "vcc-pb";
+};
+
+&reg_eldo1 {
+	regulator-min-microvolt = <1800000>;
+	regulator-max-microvolt = <1800000>;
+	regulator-name = "vdd-csi";
+	status = "okay";
+};
+
+&reg_ldo_io1 {
+	regulator-always-on;
+	regulator-min-microvolt = <1800000>;
+	regulator-max-microvolt = <1800000>;
+	regulator-name = "vcc-pm-cpus";
+	status = "okay";
+};
+
 &uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_pins_a>;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/arm/include/asm/vdso.h linux-libre-4.16-gnu/arch/arm/include/asm/vdso.h
--- linux-libre-4.16-rc7-gnu/arch/arm/include/asm/vdso.h	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/arm/include/asm/vdso.h	2018-04-01 17:20:27.000000000 -0400
@@ -12,8 +12,6 @@ struct mm_struct;
 
 void arm_install_vdso(struct mm_struct *mm, unsigned long addr);
 
-extern char vdso_start, vdso_end;
-
 extern unsigned int vdso_total_pages;
 
 #else /* CONFIG_VDSO */
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/arm/Kconfig.debug linux-libre-4.16-gnu/arch/arm/Kconfig.debug
--- linux-libre-4.16-rc7-gnu/arch/arm/Kconfig.debug	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/arm/Kconfig.debug	2018-04-01 17:20:27.000000000 -0400
@@ -22,6 +22,7 @@ config ARM_PTDUMP_DEBUGFS
 
 config DEBUG_WX
 	bool "Warn on W+X mappings at boot"
+	depends on MMU
 	select ARM_PTDUMP_CORE
 	---help---
 		Generate a warning if any W+X mappings are found at boot.
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/arm/kernel/vdso.c linux-libre-4.16-gnu/arch/arm/kernel/vdso.c
--- linux-libre-4.16-rc7-gnu/arch/arm/kernel/vdso.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/arm/kernel/vdso.c	2018-04-01 17:20:27.000000000 -0400
@@ -39,6 +39,8 @@
 
 static struct page **vdso_text_pagelist;
 
+extern char vdso_start[], vdso_end[];
+
 /* Total number of pages needed for the data and text portions of the VDSO. */
 unsigned int vdso_total_pages __ro_after_init;
 
@@ -197,13 +199,13 @@ static int __init vdso_init(void)
 	unsigned int text_pages;
 	int i;
 
-	if (memcmp(&vdso_start, "\177ELF", 4)) {
+	if (memcmp(vdso_start, "\177ELF", 4)) {
 		pr_err("VDSO is not a valid ELF object!\n");
 		return -ENOEXEC;
 	}
 
-	text_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT;
-	pr_debug("vdso: %i text pages at base %p\n", text_pages, &vdso_start);
+	text_pages = (vdso_end - vdso_start) >> PAGE_SHIFT;
+	pr_debug("vdso: %i text pages at base %p\n", text_pages, vdso_start);
 
 	/* Allocate the VDSO text pagelist */
 	vdso_text_pagelist = kcalloc(text_pages, sizeof(struct page *),
@@ -218,7 +220,7 @@ static int __init vdso_init(void)
 	for (i = 0; i < text_pages; i++) {
 		struct page *page;
 
-		page = virt_to_page(&vdso_start + i * PAGE_SIZE);
+		page = virt_to_page(vdso_start + i * PAGE_SIZE);
 		vdso_text_pagelist[i] = page;
 	}
 
@@ -229,7 +231,7 @@ static int __init vdso_init(void)
 
 	cntvct_ok = cntvct_functional();
 
-	patch_vdso(&vdso_start);
+	patch_vdso(vdso_start);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/arm/mach-davinci/board-omapl138-hawk.c linux-libre-4.16-gnu/arch/arm/mach-davinci/board-omapl138-hawk.c
--- linux-libre-4.16-rc7-gnu/arch/arm/mach-davinci/board-omapl138-hawk.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/arm/mach-davinci/board-omapl138-hawk.c	2018-04-01 17:20:27.000000000 -0400
@@ -127,8 +127,8 @@ static struct gpiod_lookup_table mmc_gpi
 	.dev_id = "da830-mmc.0",
 	.table = {
 		/* CD: gpio3_12: gpio60: chip 1 contains gpio range 32-63*/
-		GPIO_LOOKUP("davinci_gpio.1", 28, "cd", GPIO_ACTIVE_LOW),
-		GPIO_LOOKUP("davinci_gpio.1", 29, "wp", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("davinci_gpio.0", 28, "cd", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("davinci_gpio.0", 29, "wp", GPIO_ACTIVE_LOW),
 	},
 };
 
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/arm/mach-ux500/cpu-db8500.c linux-libre-4.16-gnu/arch/arm/mach-ux500/cpu-db8500.c
--- linux-libre-4.16-rc7-gnu/arch/arm/mach-ux500/cpu-db8500.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/arm/mach-ux500/cpu-db8500.c	2018-04-01 17:20:27.000000000 -0400
@@ -133,6 +133,9 @@ static void __init u8500_init_machine(vo
 	if (of_machine_is_compatible("st-ericsson,u8540"))
 		of_platform_populate(NULL, u8500_local_bus_nodes,
 				     u8540_auxdata_lookup, NULL);
+	else
+		of_platform_populate(NULL, u8500_local_bus_nodes,
+				     NULL, NULL);
 }
 
 static const char * stericsson_dt_platform_compat[] = {
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/arm/plat-omap/dmtimer.c linux-libre-4.16-gnu/arch/arm/plat-omap/dmtimer.c
--- linux-libre-4.16-rc7-gnu/arch/arm/plat-omap/dmtimer.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/arm/plat-omap/dmtimer.c	2018-04-01 17:20:27.000000000 -0400
@@ -888,11 +888,8 @@ static int omap_dm_timer_probe(struct pl
 	timer->irq = irq->start;
 	timer->pdev = pdev;
 
-	/* Skip pm_runtime_enable for OMAP1 */
-	if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) {
-		pm_runtime_enable(dev);
-		pm_runtime_irq_safe(dev);
-	}
+	pm_runtime_enable(dev);
+	pm_runtime_irq_safe(dev);
 
 	if (!timer->reserved) {
 		ret = pm_runtime_get_sync(dev);
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/arm/plat-omap/include/plat/sram.h linux-libre-4.16-gnu/arch/arm/plat-omap/include/plat/sram.h
--- linux-libre-4.16-rc7-gnu/arch/arm/plat-omap/include/plat/sram.h	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/arm/plat-omap/include/plat/sram.h	2018-04-01 17:20:27.000000000 -0400
@@ -5,13 +5,4 @@ void omap_map_sram(unsigned long start,
 			unsigned long skip, int cached);
 void omap_sram_reset(void);
 
-extern void *omap_sram_push_address(unsigned long size);
-
-/* Macro to push a function to the internal SRAM, using the fncpy API */
-#define omap_sram_push(funcp, size) ({				\
-	typeof(&(funcp)) _res = NULL;				\
-	void *_sram_address = omap_sram_push_address(size);	\
-	if (_sram_address)					\
-		_res = fncpy(_sram_address, &(funcp), size);	\
-	_res;							\
-})
+extern void *omap_sram_push(void *funcp, unsigned long size);
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/arm/plat-omap/sram.c linux-libre-4.16-gnu/arch/arm/plat-omap/sram.c
--- linux-libre-4.16-rc7-gnu/arch/arm/plat-omap/sram.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/arm/plat-omap/sram.c	2018-04-01 17:20:27.000000000 -0400
@@ -23,6 +23,7 @@
 #include <asm/fncpy.h>
 #include <asm/tlb.h>
 #include <asm/cacheflush.h>
+#include <asm/set_memory.h>
 
 #include <asm/mach/map.h>
 
@@ -42,7 +43,7 @@ static void __iomem *omap_sram_ceil;
  * Note that fncpy requires the returned address to be aligned
  * to an 8-byte boundary.
  */
-void *omap_sram_push_address(unsigned long size)
+static void *omap_sram_push_address(unsigned long size)
 {
 	unsigned long available, new_ceil = (unsigned long)omap_sram_ceil;
 
@@ -60,6 +61,30 @@ void *omap_sram_push_address(unsigned lo
 	return (void *)omap_sram_ceil;
 }
 
+void *omap_sram_push(void *funcp, unsigned long size)
+{
+	void *sram;
+	unsigned long base;
+	int pages;
+	void *dst = NULL;
+
+	sram = omap_sram_push_address(size);
+	if (!sram)
+		return NULL;
+
+	base = (unsigned long)sram & PAGE_MASK;
+	pages = PAGE_ALIGN(size) / PAGE_SIZE;
+
+	set_memory_rw(base, pages);
+
+	dst = fncpy(sram, funcp, size);
+
+	set_memory_ro(base, pages);
+	set_memory_x(base, pages);
+
+	return dst;
+}
+
 /*
  * The SRAM context is lost during off-idle and stack
  * needs to be reset.
@@ -75,6 +100,9 @@ void omap_sram_reset(void)
 void __init omap_map_sram(unsigned long start, unsigned long size,
 				 unsigned long skip, int cached)
 {
+	unsigned long base;
+	int pages;
+
 	if (size == 0)
 		return;
 
@@ -95,4 +123,10 @@ void __init omap_map_sram(unsigned long
 	 */
 	memset_io(omap_sram_base + omap_sram_skip, 0,
 		  omap_sram_size - omap_sram_skip);
+
+	base = (unsigned long)omap_sram_base;
+	pages = PAGE_ALIGN(omap_sram_size) / PAGE_SIZE;
+
+	set_memory_ro(base, pages);
+	set_memory_x(base, pages);
 }
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/arm/vfp/vfpmodule.c linux-libre-4.16-gnu/arch/arm/vfp/vfpmodule.c
--- linux-libre-4.16-rc7-gnu/arch/arm/vfp/vfpmodule.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/arm/vfp/vfpmodule.c	2018-04-01 17:20:27.000000000 -0400
@@ -648,7 +648,7 @@ int vfp_restore_user_hwstate(struct user
  */
 static int vfp_dying_cpu(unsigned int cpu)
 {
-	vfp_force_reload(cpu, current_thread_info());
+	vfp_current_hw_state[cpu] = NULL;
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/arm64/boot/dts/rockchip/rk3399.dtsi linux-libre-4.16-gnu/arch/arm64/boot/dts/rockchip/rk3399.dtsi
--- linux-libre-4.16-rc7-gnu/arch/arm64/boot/dts/rockchip/rk3399.dtsi	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/arm64/boot/dts/rockchip/rk3399.dtsi	2018-04-01 17:20:27.000000000 -0400
@@ -411,8 +411,8 @@
 			reg = <0x0 0xfe800000 0x0 0x100000>;
 			interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH 0>;
 			dr_mode = "otg";
-			phys = <&u2phy0_otg>, <&tcphy0_usb3>;
-			phy-names = "usb2-phy", "usb3-phy";
+			phys = <&u2phy0_otg>;
+			phy-names = "usb2-phy";
 			phy_type = "utmi_wide";
 			snps,dis_enblslpm_quirk;
 			snps,dis-u2-freeclk-exists-quirk;
@@ -444,8 +444,8 @@
 			reg = <0x0 0xfe900000 0x0 0x100000>;
 			interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH 0>;
 			dr_mode = "otg";
-			phys = <&u2phy1_otg>, <&tcphy1_usb3>;
-			phy-names = "usb2-phy", "usb3-phy";
+			phys = <&u2phy1_otg>;
+			phy-names = "usb2-phy";
 			phy_type = "utmi_wide";
 			snps,dis_enblslpm_quirk;
 			snps,dis-u2-freeclk-exists-quirk;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi linux-libre-4.16-gnu/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
--- linux-libre-4.16-rc7-gnu/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi	2018-04-01 17:20:27.000000000 -0400
@@ -406,8 +406,9 @@
 	wlan_pd_n: wlan-pd-n {
 		compatible = "regulator-fixed";
 		regulator-name = "wlan_pd_n";
+		pinctrl-names = "default";
+		pinctrl-0 = <&wlan_module_reset_l>;
 
-		/* Note the wlan_module_reset_l pinctrl */
 		enable-active-high;
 		gpio = <&gpio1 11 GPIO_ACTIVE_HIGH>;
 
@@ -983,12 +984,6 @@ ap_i2c_audio: &i2c8 {
 	pinctrl-0 = <
 		&ap_pwroff	/* AP will auto-assert this when in S3 */
 		&clk_32k	/* This pin is always 32k on gru boards */
-
-		/*
-		 * We want this driven low ASAP; firmware should help us, but
-		 * we can help ourselves too.
-		 */
-		&wlan_module_reset_l
 	>;
 
 	pcfg_output_low: pcfg-output-low {
@@ -1168,12 +1163,7 @@ ap_i2c_audio: &i2c8 {
 		};
 
 		wlan_module_reset_l: wlan-module-reset-l {
-			/*
-			 * We want this driven low ASAP (As {Soon,Strongly} As
-			 * Possible), to avoid leakage through the powered-down
-			 * WiFi.
-			 */
-			rockchip,pins = <1 11 RK_FUNC_GPIO &pcfg_output_low>;
+			rockchip,pins = <1 11 RK_FUNC_GPIO &pcfg_pull_none>;
 		};
 
 		bt_host_wake_l: bt-host-wake-l {
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/powerpc/include/asm/book3s/64/mmu.h linux-libre-4.16-gnu/arch/powerpc/include/asm/book3s/64/mmu.h
--- linux-libre-4.16-rc7-gnu/arch/powerpc/include/asm/book3s/64/mmu.h	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/powerpc/include/asm/book3s/64/mmu.h	2018-04-01 17:20:27.000000000 -0400
@@ -87,6 +87,9 @@ typedef struct {
 	/* Number of bits in the mm_cpumask */
 	atomic_t active_cpus;
 
+	/* Number of users of the external (Nest) MMU */
+	atomic_t copros;
+
 	/* NPU NMMU context */
 	struct npu_context *npu_context;
 
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/powerpc/include/asm/book3s/64/tlbflush-radix.h linux-libre-4.16-gnu/arch/powerpc/include/asm/book3s/64/tlbflush-radix.h
--- linux-libre-4.16-rc7-gnu/arch/powerpc/include/asm/book3s/64/tlbflush-radix.h	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/powerpc/include/asm/book3s/64/tlbflush-radix.h	2018-04-01 17:20:27.000000000 -0400
@@ -47,9 +47,6 @@ extern void radix__flush_tlb_page_psize(
 #endif
 extern void radix__flush_tlb_pwc(struct mmu_gather *tlb, unsigned long addr);
 extern void radix__flush_tlb_collapsed_pmd(struct mm_struct *mm, unsigned long addr);
-extern void radix__flush_tlb_lpid_va(unsigned long lpid, unsigned long gpa,
-				     unsigned long page_size);
-extern void radix__flush_tlb_lpid(unsigned long lpid);
 extern void radix__flush_tlb_all(void);
 extern void radix__flush_tlb_pte_p9_dd1(unsigned long old_pte, struct mm_struct *mm,
 					unsigned long address);
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/powerpc/include/asm/cputable.h linux-libre-4.16-gnu/arch/powerpc/include/asm/cputable.h
--- linux-libre-4.16-rc7-gnu/arch/powerpc/include/asm/cputable.h	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/powerpc/include/asm/cputable.h	2018-04-01 17:20:27.000000000 -0400
@@ -203,6 +203,7 @@ static inline void cpu_feature_keys_init
 #define CPU_FTR_DAWR			LONG_ASM_CONST(0x0400000000000000)
 #define CPU_FTR_DABRX			LONG_ASM_CONST(0x0800000000000000)
 #define CPU_FTR_PMAO_BUG		LONG_ASM_CONST(0x1000000000000000)
+#define CPU_FTR_P9_TLBIE_BUG		LONG_ASM_CONST(0x2000000000000000)
 #define CPU_FTR_POWER9_DD1		LONG_ASM_CONST(0x4000000000000000)
 #define CPU_FTR_POWER9_DD2_1		LONG_ASM_CONST(0x8000000000000000)
 
@@ -465,7 +466,7 @@ static inline void cpu_feature_keys_init
 	    CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \
 	    CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \
 	    CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP | CPU_FTR_ARCH_300 | \
-	    CPU_FTR_PKEY)
+	    CPU_FTR_PKEY | CPU_FTR_P9_TLBIE_BUG)
 #define CPU_FTRS_POWER9_DD1 ((CPU_FTRS_POWER9 | CPU_FTR_POWER9_DD1) & \
 			     (~CPU_FTR_SAO))
 #define CPU_FTRS_POWER9_DD2_0 CPU_FTRS_POWER9
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/powerpc/include/asm/mmu_context.h linux-libre-4.16-gnu/arch/powerpc/include/asm/mmu_context.h
--- linux-libre-4.16-rc7-gnu/arch/powerpc/include/asm/mmu_context.h	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/powerpc/include/asm/mmu_context.h	2018-04-01 17:20:27.000000000 -0400
@@ -92,15 +92,23 @@ static inline void dec_mm_active_cpus(st
 static inline void mm_context_add_copro(struct mm_struct *mm)
 {
 	/*
-	 * On hash, should only be called once over the lifetime of
-	 * the context, as we can't decrement the active cpus count
-	 * and flush properly for the time being.
+	 * If any copro is in use, increment the active CPU count
+	 * in order to force TLB invalidations to be global as to
+	 * propagate to the Nest MMU.
 	 */
-	inc_mm_active_cpus(mm);
+	if (atomic_inc_return(&mm->context.copros) == 1)
+		inc_mm_active_cpus(mm);
 }
 
 static inline void mm_context_remove_copro(struct mm_struct *mm)
 {
+	int c;
+
+	c = atomic_dec_if_positive(&mm->context.copros);
+
+	/* Detect imbalance between add and remove */
+	WARN_ON(c < 0);
+
 	/*
 	 * Need to broadcast a global flush of the full mm before
 	 * decrementing active_cpus count, as the next TLBI may be
@@ -111,7 +119,7 @@ static inline void mm_context_remove_cop
 	 * for the time being. Invalidations will remain global if
 	 * used on hash.
 	 */
-	if (radix_enabled()) {
+	if (c == 0 && radix_enabled()) {
 		flush_all_mm(mm);
 		dec_mm_active_cpus(mm);
 	}
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/powerpc/kernel/dt_cpu_ftrs.c linux-libre-4.16-gnu/arch/powerpc/kernel/dt_cpu_ftrs.c
--- linux-libre-4.16-rc7-gnu/arch/powerpc/kernel/dt_cpu_ftrs.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/powerpc/kernel/dt_cpu_ftrs.c	2018-04-01 17:20:27.000000000 -0400
@@ -709,6 +709,9 @@ static __init void cpufeatures_cpu_quirk
 		cur_cpu_spec->cpu_features |= CPU_FTR_POWER9_DD1;
 	else if ((version & 0xffffefff) == 0x004e0201)
 		cur_cpu_spec->cpu_features |= CPU_FTR_POWER9_DD2_1;
+
+	if ((version & 0xffff0000) == 0x004e0000)
+		cur_cpu_spec->cpu_features |= CPU_FTR_P9_TLBIE_BUG;
 }
 
 static void __init cpufeatures_setup_finished(void)
@@ -720,6 +723,9 @@ static void __init cpufeatures_setup_fin
 		cur_cpu_spec->cpu_features |= CPU_FTR_HVMODE;
 	}
 
+	/* Make sure powerpc_base_platform is non-NULL */
+	powerpc_base_platform = cur_cpu_spec->platform;
+
 	system_registers.lpcr = mfspr(SPRN_LPCR);
 	system_registers.hfscr = mfspr(SPRN_HFSCR);
 	system_registers.fscr = mfspr(SPRN_FSCR);
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/powerpc/kernel/exceptions-64s.S linux-libre-4.16-gnu/arch/powerpc/kernel/exceptions-64s.S
--- linux-libre-4.16-rc7-gnu/arch/powerpc/kernel/exceptions-64s.S	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/powerpc/kernel/exceptions-64s.S	2018-04-01 17:20:27.000000000 -0400
@@ -706,7 +706,7 @@ EXC_COMMON_BEGIN(bad_addr_slb)
 	ld	r3, PACA_EXSLB+EX_DAR(r13)
 	std	r3, _DAR(r1)
 	beq	cr6, 2f
-	li	r10, 0x480		/* fix trap number for I-SLB miss */
+	li	r10, 0x481		/* fix trap number for I-SLB miss */
 	std	r10, _TRAP(r1)
 2:	bl	save_nvgprs
 	addi	r3, r1, STACK_FRAME_OVERHEAD
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/powerpc/kernel/irq.c linux-libre-4.16-gnu/arch/powerpc/kernel/irq.c
--- linux-libre-4.16-rc7-gnu/arch/powerpc/kernel/irq.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/powerpc/kernel/irq.c	2018-04-01 17:20:27.000000000 -0400
@@ -476,6 +476,14 @@ void force_external_irq_replay(void)
 	 */
 	WARN_ON(!arch_irqs_disabled());
 
+	/*
+	 * Interrupts must always be hard disabled before irq_happened is
+	 * modified (to prevent lost update in case of interrupt between
+	 * load and store).
+	 */
+	__hard_irq_disable();
+	local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
+
 	/* Indicate in the PACA that we have an interrupt to replay */
 	local_paca->irq_happened |= PACA_IRQ_EE;
 }
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/powerpc/kvm/book3s_64_mmu_radix.c linux-libre-4.16-gnu/arch/powerpc/kvm/book3s_64_mmu_radix.c
--- linux-libre-4.16-rc7-gnu/arch/powerpc/kvm/book3s_64_mmu_radix.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/powerpc/kvm/book3s_64_mmu_radix.c	2018-04-01 17:20:27.000000000 -0400
@@ -157,6 +157,9 @@ static void kvmppc_radix_tlbie_page(stru
 	asm volatile("ptesync": : :"memory");
 	asm volatile(PPC_TLBIE_5(%0, %1, 0, 0, 1)
 		     : : "r" (addr), "r" (kvm->arch.lpid) : "memory");
+	if (cpu_has_feature(CPU_FTR_P9_TLBIE_BUG))
+		asm volatile(PPC_TLBIE_5(%0, %1, 0, 0, 1)
+			     : : "r" (addr), "r" (kvm->arch.lpid) : "memory");
 	asm volatile("ptesync": : :"memory");
 }
 
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/powerpc/kvm/book3s_hv_rmhandlers.S linux-libre-4.16-gnu/arch/powerpc/kvm/book3s_hv_rmhandlers.S
--- linux-libre-4.16-rc7-gnu/arch/powerpc/kvm/book3s_hv_rmhandlers.S	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/powerpc/kvm/book3s_hv_rmhandlers.S	2018-04-01 17:20:27.000000000 -0400
@@ -1557,6 +1557,24 @@ mc_cont:
 	ptesync
 3:	stw	r5,VCPU_SLB_MAX(r9)
 
+	/* load host SLB entries */
+BEGIN_MMU_FTR_SECTION
+	b	0f
+END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_RADIX)
+	ld	r8,PACA_SLBSHADOWPTR(r13)
+
+	.rept	SLB_NUM_BOLTED
+	li	r3, SLBSHADOW_SAVEAREA
+	LDX_BE	r5, r8, r3
+	addi	r3, r3, 8
+	LDX_BE	r6, r8, r3
+	andis.	r7,r5,SLB_ESID_V@h
+	beq	1f
+	slbmte	r6,r5
+1:	addi	r8,r8,16
+	.endr
+0:
+
 guest_bypass:
 	stw	r12, STACK_SLOT_TRAP(r1)
 	mr 	r3, r12
@@ -2018,23 +2036,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
 	mtspr	SPRN_LPCR,r8
 	isync
 48:
-	/* load host SLB entries */
-BEGIN_MMU_FTR_SECTION
-	b	0f
-END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_RADIX)
-	ld	r8,PACA_SLBSHADOWPTR(r13)
-
-	.rept	SLB_NUM_BOLTED
-	li	r3, SLBSHADOW_SAVEAREA
-	LDX_BE	r5, r8, r3
-	addi	r3, r3, 8
-	LDX_BE	r6, r8, r3
-	andis.	r7,r5,SLB_ESID_V@h
-	beq	1f
-	slbmte	r6,r5
-1:	addi	r8,r8,16
-	.endr
-0:
 #ifdef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING
 	/* Finish timing, if we have a vcpu */
 	ld	r4, HSTATE_KVM_VCPU(r13)
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/powerpc/kvm/book3s_hv_rm_mmu.c linux-libre-4.16-gnu/arch/powerpc/kvm/book3s_hv_rm_mmu.c
--- linux-libre-4.16-rc7-gnu/arch/powerpc/kvm/book3s_hv_rm_mmu.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/powerpc/kvm/book3s_hv_rm_mmu.c	2018-04-01 17:20:27.000000000 -0400
@@ -473,6 +473,17 @@ static void do_tlbies(struct kvm *kvm, u
 			trace_tlbie(kvm->arch.lpid, 0, rbvalues[i],
 				kvm->arch.lpid, 0, 0, 0);
 		}
+
+		if (cpu_has_feature(CPU_FTR_P9_TLBIE_BUG)) {
+			/*
+			 * Need the extra ptesync to make sure we don't
+			 * re-order the tlbie
+			 */
+			asm volatile("ptesync": : :"memory");
+			asm volatile(PPC_TLBIE_5(%0,%1,0,0,0) : :
+				     "r" (rbvalues[0]), "r" (kvm->arch.lpid));
+		}
+
 		asm volatile("eieio; tlbsync; ptesync" : : : "memory");
 		kvm->arch.tlbie_lock = 0;
 	} else {
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/powerpc/mm/hash_native_64.c linux-libre-4.16-gnu/arch/powerpc/mm/hash_native_64.c
--- linux-libre-4.16-rc7-gnu/arch/powerpc/mm/hash_native_64.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/powerpc/mm/hash_native_64.c	2018-04-01 17:20:27.000000000 -0400
@@ -201,6 +201,15 @@ static inline unsigned long  ___tlbie(un
 	return va;
 }
 
+static inline void fixup_tlbie(unsigned long vpn, int psize, int apsize, int ssize)
+{
+	if (cpu_has_feature(CPU_FTR_P9_TLBIE_BUG)) {
+		/* Need the extra ptesync to ensure we don't reorder tlbie*/
+		asm volatile("ptesync": : :"memory");
+		___tlbie(vpn, psize, apsize, ssize);
+	}
+}
+
 static inline void __tlbie(unsigned long vpn, int psize, int apsize, int ssize)
 {
 	unsigned long rb;
@@ -278,6 +287,7 @@ static inline void tlbie(unsigned long v
 		asm volatile("ptesync": : :"memory");
 	} else {
 		__tlbie(vpn, psize, apsize, ssize);
+		fixup_tlbie(vpn, psize, apsize, ssize);
 		asm volatile("eieio; tlbsync; ptesync": : :"memory");
 	}
 	if (lock_tlbie && !use_local)
@@ -771,7 +781,7 @@ static void native_hpte_clear(void)
  */
 static void native_flush_hash_range(unsigned long number, int local)
 {
-	unsigned long vpn;
+	unsigned long vpn = 0;
 	unsigned long hash, index, hidx, shift, slot;
 	struct hash_pte *hptep;
 	unsigned long hpte_v;
@@ -843,6 +853,10 @@ static void native_flush_hash_range(unsi
 				__tlbie(vpn, psize, psize, ssize);
 			} pte_iterate_hashed_end();
 		}
+		/*
+		 * Just do one more with the last used values.
+		 */
+		fixup_tlbie(vpn, psize, psize, ssize);
 		asm volatile("eieio; tlbsync; ptesync":::"memory");
 
 		if (lock_tlbie)
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/powerpc/mm/mmu_context_book3s64.c linux-libre-4.16-gnu/arch/powerpc/mm/mmu_context_book3s64.c
--- linux-libre-4.16-rc7-gnu/arch/powerpc/mm/mmu_context_book3s64.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/powerpc/mm/mmu_context_book3s64.c	2018-04-01 17:20:27.000000000 -0400
@@ -173,6 +173,7 @@ int init_new_context(struct task_struct
 	mm_iommu_init(mm);
 #endif
 	atomic_set(&mm->context.active_cpus, 0);
+	atomic_set(&mm->context.copros, 0);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/powerpc/mm/pgtable_64.c linux-libre-4.16-gnu/arch/powerpc/mm/pgtable_64.c
--- linux-libre-4.16-rc7-gnu/arch/powerpc/mm/pgtable_64.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/powerpc/mm/pgtable_64.c	2018-04-01 17:20:27.000000000 -0400
@@ -481,6 +481,7 @@ void mmu_partition_table_set_entry(unsig
 			     "r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
 		trace_tlbie(lpid, 0, TLBIEL_INVAL_SET_LPID, lpid, 2, 0, 0);
 	}
+	/* do we need fixup here ?*/
 	asm volatile("eieio; tlbsync; ptesync" : : : "memory");
 }
 EXPORT_SYMBOL_GPL(mmu_partition_table_set_entry);
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/powerpc/mm/tlb-radix.c linux-libre-4.16-gnu/arch/powerpc/mm/tlb-radix.c
--- linux-libre-4.16-rc7-gnu/arch/powerpc/mm/tlb-radix.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/powerpc/mm/tlb-radix.c	2018-04-01 17:20:27.000000000 -0400
@@ -119,6 +119,49 @@ static inline void __tlbie_pid(unsigned
 	trace_tlbie(0, 0, rb, rs, ric, prs, r);
 }
 
+static inline void __tlbiel_va(unsigned long va, unsigned long pid,
+			       unsigned long ap, unsigned long ric)
+{
+	unsigned long rb,rs,prs,r;
+
+	rb = va & ~(PPC_BITMASK(52, 63));
+	rb |= ap << PPC_BITLSHIFT(58);
+	rs = pid << PPC_BITLSHIFT(31);
+	prs = 1; /* process scoped */
+	r = 1;   /* raidx format */
+
+	asm volatile(PPC_TLBIEL(%0, %4, %3, %2, %1)
+		     : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory");
+	trace_tlbie(0, 1, rb, rs, ric, prs, r);
+}
+
+static inline void __tlbie_va(unsigned long va, unsigned long pid,
+			      unsigned long ap, unsigned long ric)
+{
+	unsigned long rb,rs,prs,r;
+
+	rb = va & ~(PPC_BITMASK(52, 63));
+	rb |= ap << PPC_BITLSHIFT(58);
+	rs = pid << PPC_BITLSHIFT(31);
+	prs = 1; /* process scoped */
+	r = 1;   /* raidx format */
+
+	asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1)
+		     : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory");
+	trace_tlbie(0, 0, rb, rs, ric, prs, r);
+}
+
+static inline void fixup_tlbie(void)
+{
+	unsigned long pid = 0;
+	unsigned long va = ((1UL << 52) - 1);
+
+	if (cpu_has_feature(CPU_FTR_P9_TLBIE_BUG)) {
+		asm volatile("ptesync": : :"memory");
+		__tlbie_va(va, pid, mmu_get_ap(MMU_PAGE_64K), RIC_FLUSH_TLB);
+	}
+}
+
 /*
  * We use 128 set in radix mode and 256 set in hpt mode.
  */
@@ -151,24 +194,25 @@ static inline void _tlbiel_pid(unsigned
 static inline void _tlbie_pid(unsigned long pid, unsigned long ric)
 {
 	asm volatile("ptesync": : :"memory");
-	__tlbie_pid(pid, ric);
-	asm volatile("eieio; tlbsync; ptesync": : :"memory");
-}
 
-static inline void __tlbiel_va(unsigned long va, unsigned long pid,
-			       unsigned long ap, unsigned long ric)
-{
-	unsigned long rb,rs,prs,r;
-
-	rb = va & ~(PPC_BITMASK(52, 63));
-	rb |= ap << PPC_BITLSHIFT(58);
-	rs = pid << PPC_BITLSHIFT(31);
-	prs = 1; /* process scoped */
-	r = 1;   /* raidx format */
-
-	asm volatile(PPC_TLBIEL(%0, %4, %3, %2, %1)
-		     : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory");
-	trace_tlbie(0, 1, rb, rs, ric, prs, r);
+	/*
+	 * Workaround the fact that the "ric" argument to __tlbie_pid
+	 * must be a compile-time contraint to match the "i" constraint
+	 * in the asm statement.
+	 */
+	switch (ric) {
+	case RIC_FLUSH_TLB:
+		__tlbie_pid(pid, RIC_FLUSH_TLB);
+		break;
+	case RIC_FLUSH_PWC:
+		__tlbie_pid(pid, RIC_FLUSH_PWC);
+		break;
+	case RIC_FLUSH_ALL:
+	default:
+		__tlbie_pid(pid, RIC_FLUSH_ALL);
+	}
+	fixup_tlbie();
+	asm volatile("eieio; tlbsync; ptesync": : :"memory");
 }
 
 static inline void __tlbiel_va_range(unsigned long start, unsigned long end,
@@ -203,22 +247,6 @@ static inline void _tlbiel_va_range(unsi
 	asm volatile("ptesync": : :"memory");
 }
 
-static inline void __tlbie_va(unsigned long va, unsigned long pid,
-			     unsigned long ap, unsigned long ric)
-{
-	unsigned long rb,rs,prs,r;
-
-	rb = va & ~(PPC_BITMASK(52, 63));
-	rb |= ap << PPC_BITLSHIFT(58);
-	rs = pid << PPC_BITLSHIFT(31);
-	prs = 1; /* process scoped */
-	r = 1;   /* raidx format */
-
-	asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1)
-		     : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory");
-	trace_tlbie(0, 0, rb, rs, ric, prs, r);
-}
-
 static inline void __tlbie_va_range(unsigned long start, unsigned long end,
 				    unsigned long pid, unsigned long page_size,
 				    unsigned long psize)
@@ -237,6 +265,7 @@ static inline void _tlbie_va(unsigned lo
 
 	asm volatile("ptesync": : :"memory");
 	__tlbie_va(va, pid, ap, ric);
+	fixup_tlbie();
 	asm volatile("eieio; tlbsync; ptesync": : :"memory");
 }
 
@@ -248,6 +277,7 @@ static inline void _tlbie_va_range(unsig
 	if (also_pwc)
 		__tlbie_pid(pid, RIC_FLUSH_PWC);
 	__tlbie_va_range(start, end, pid, page_size, psize);
+	fixup_tlbie();
 	asm volatile("eieio; tlbsync; ptesync": : :"memory");
 }
 
@@ -311,6 +341,16 @@ void radix__local_flush_tlb_page(struct
 }
 EXPORT_SYMBOL(radix__local_flush_tlb_page);
 
+static bool mm_needs_flush_escalation(struct mm_struct *mm)
+{
+	/*
+	 * P9 nest MMU has issues with the page walk cache
+	 * caching PTEs and not flushing them properly when
+	 * RIC = 0 for a PID/LPID invalidate
+	 */
+	return atomic_read(&mm->context.copros) != 0;
+}
+
 #ifdef CONFIG_SMP
 void radix__flush_tlb_mm(struct mm_struct *mm)
 {
@@ -321,9 +361,12 @@ void radix__flush_tlb_mm(struct mm_struc
 		return;
 
 	preempt_disable();
-	if (!mm_is_thread_local(mm))
-		_tlbie_pid(pid, RIC_FLUSH_TLB);
-	else
+	if (!mm_is_thread_local(mm)) {
+		if (mm_needs_flush_escalation(mm))
+			_tlbie_pid(pid, RIC_FLUSH_ALL);
+		else
+			_tlbie_pid(pid, RIC_FLUSH_TLB);
+	} else
 		_tlbiel_pid(pid, RIC_FLUSH_TLB);
 	preempt_enable();
 }
@@ -435,10 +478,14 @@ void radix__flush_tlb_range(struct vm_ar
 	}
 
 	if (full) {
-		if (local)
+		if (local) {
 			_tlbiel_pid(pid, RIC_FLUSH_TLB);
-		else
-			_tlbie_pid(pid, RIC_FLUSH_TLB);
+		} else {
+			if (mm_needs_flush_escalation(mm))
+				_tlbie_pid(pid, RIC_FLUSH_ALL);
+			else
+				_tlbie_pid(pid, RIC_FLUSH_TLB);
+		}
 	} else {
 		bool hflush = false;
 		unsigned long hstart, hend;
@@ -465,6 +512,7 @@ void radix__flush_tlb_range(struct vm_ar
 			if (hflush)
 				__tlbie_va_range(hstart, hend, pid,
 						HPAGE_PMD_SIZE, MMU_PAGE_2M);
+			fixup_tlbie();
 			asm volatile("eieio; tlbsync; ptesync": : :"memory");
 		}
 	}
@@ -548,6 +596,9 @@ static inline void __radix__flush_tlb_ra
 	}
 
 	if (full) {
+		if (!local && mm_needs_flush_escalation(mm))
+			also_pwc = true;
+
 		if (local)
 			_tlbiel_pid(pid, also_pwc ? RIC_FLUSH_ALL : RIC_FLUSH_TLB);
 		else
@@ -603,46 +654,6 @@ void radix__flush_tlb_collapsed_pmd(stru
 }
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 
-void radix__flush_tlb_lpid_va(unsigned long lpid, unsigned long gpa,
-			      unsigned long page_size)
-{
-	unsigned long rb,rs,prs,r;
-	unsigned long ap;
-	unsigned long ric = RIC_FLUSH_TLB;
-
-	ap = mmu_get_ap(radix_get_mmu_psize(page_size));
-	rb = gpa & ~(PPC_BITMASK(52, 63));
-	rb |= ap << PPC_BITLSHIFT(58);
-	rs = lpid & ((1UL << 32) - 1);
-	prs = 0; /* process scoped */
-	r = 1;   /* raidx format */
-
-	asm volatile("ptesync": : :"memory");
-	asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1)
-		     : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory");
-	asm volatile("eieio; tlbsync; ptesync": : :"memory");
-	trace_tlbie(lpid, 0, rb, rs, ric, prs, r);
-}
-EXPORT_SYMBOL(radix__flush_tlb_lpid_va);
-
-void radix__flush_tlb_lpid(unsigned long lpid)
-{
-	unsigned long rb,rs,prs,r;
-	unsigned long ric = RIC_FLUSH_ALL;
-
-	rb = 0x2 << PPC_BITLSHIFT(53); /* IS = 2 */
-	rs = lpid & ((1UL << 32) - 1);
-	prs = 0; /* partition scoped */
-	r = 1;   /* raidx format */
-
-	asm volatile("ptesync": : :"memory");
-	asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1)
-		     : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory");
-	asm volatile("eieio; tlbsync; ptesync": : :"memory");
-	trace_tlbie(lpid, 0, rb, rs, ric, prs, r);
-}
-EXPORT_SYMBOL(radix__flush_tlb_lpid);
-
 void radix__flush_pmd_tlb_range(struct vm_area_struct *vma,
 				unsigned long start, unsigned long end)
 {
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/x86/events/intel/ds.c linux-libre-4.16-gnu/arch/x86/events/intel/ds.c
--- linux-libre-4.16-rc7-gnu/arch/x86/events/intel/ds.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/x86/events/intel/ds.c	2018-04-01 17:20:27.000000000 -0400
@@ -1153,6 +1153,7 @@ static void setup_pebs_sample_data(struc
 	if (pebs == NULL)
 		return;
 
+	regs->flags &= ~PERF_EFLAGS_EXACT;
 	sample_type = event->attr.sample_type;
 	dsrc = sample_type & PERF_SAMPLE_DATA_SRC;
 
@@ -1197,7 +1198,6 @@ static void setup_pebs_sample_data(struc
 	 */
 	*regs = *iregs;
 	regs->flags = pebs->flags;
-	set_linear_ip(regs, pebs->ip);
 
 	if (sample_type & PERF_SAMPLE_REGS_INTR) {
 		regs->ax = pebs->ax;
@@ -1233,13 +1233,22 @@ static void setup_pebs_sample_data(struc
 #endif
 	}
 
-	if (event->attr.precise_ip > 1 && x86_pmu.intel_cap.pebs_format >= 2) {
-		regs->ip = pebs->real_ip;
-		regs->flags |= PERF_EFLAGS_EXACT;
-	} else if (event->attr.precise_ip > 1 && intel_pmu_pebs_fixup_ip(regs))
-		regs->flags |= PERF_EFLAGS_EXACT;
-	else
-		regs->flags &= ~PERF_EFLAGS_EXACT;
+	if (event->attr.precise_ip > 1) {
+		/* Haswell and later have the eventing IP, so use it: */
+		if (x86_pmu.intel_cap.pebs_format >= 2) {
+			set_linear_ip(regs, pebs->real_ip);
+			regs->flags |= PERF_EFLAGS_EXACT;
+		} else {
+			/* Otherwise use PEBS off-by-1 IP: */
+			set_linear_ip(regs, pebs->ip);
+
+			/* ... and try to fix it up using the LBR entries: */
+			if (intel_pmu_pebs_fixup_ip(regs))
+				regs->flags |= PERF_EFLAGS_EXACT;
+		}
+	} else
+		set_linear_ip(regs, pebs->ip);
+
 
 	if ((sample_type & (PERF_SAMPLE_ADDR | PERF_SAMPLE_PHYS_ADDR)) &&
 	    x86_pmu.intel_cap.pebs_format >= 1)
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/x86/include/asm/alternative.h linux-libre-4.16-gnu/arch/x86/include/asm/alternative.h
--- linux-libre-4.16-rc7-gnu/arch/x86/include/asm/alternative.h	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/x86/include/asm/alternative.h	2018-04-01 17:20:27.000000000 -0400
@@ -218,13 +218,11 @@ static inline int alternatives_text_rese
  */
 #define alternative_call_2(oldfunc, newfunc1, feature1, newfunc2, feature2,   \
 			   output, input...)				      \
-{									      \
 	asm volatile (ALTERNATIVE_2("call %P[old]", "call %P[new1]", feature1,\
 		"call %P[new2]", feature2)				      \
 		: output, ASM_CALL_CONSTRAINT				      \
 		: [old] "i" (oldfunc), [new1] "i" (newfunc1),		      \
-		  [new2] "i" (newfunc2), ## input);			      \
-}
+		  [new2] "i" (newfunc2), ## input)
 
 /*
  * use this macro(s) if you need more than one output parameter
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/x86/include/asm/hw_irq.h linux-libre-4.16-gnu/arch/x86/include/asm/hw_irq.h
--- linux-libre-4.16-rc7-gnu/arch/x86/include/asm/hw_irq.h	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/x86/include/asm/hw_irq.h	2018-04-01 17:20:27.000000000 -0400
@@ -36,6 +36,7 @@ extern asmlinkage void kvm_posted_intr_w
 extern asmlinkage void kvm_posted_intr_nested_ipi(void);
 extern asmlinkage void error_interrupt(void);
 extern asmlinkage void irq_work_interrupt(void);
+extern asmlinkage void uv_bau_message_intr1(void);
 
 extern asmlinkage void spurious_interrupt(void);
 extern asmlinkage void thermal_interrupt(void);
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/x86/include/asm/uv/uv_mmrs.h linux-libre-4.16-gnu/arch/x86/include/asm/uv/uv_mmrs.h
--- linux-libre-4.16-rc7-gnu/arch/x86/include/asm/uv/uv_mmrs.h	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/x86/include/asm/uv/uv_mmrs.h	2018-04-01 17:20:27.000000000 -0400
@@ -3833,7 +3833,7 @@ union uvh_rh_gam_mmioh_overlay_config0_m
 #define UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR uv_undefined("UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR")
 #define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR uv_undefined("UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR")
 #define UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR 0x1603000UL
-#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR 0x483000UL
+#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR 0x484000UL
 #define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR (				\
 	is_uv1_hub() ? UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR :		\
 	is_uv2_hub() ? UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR :		\
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/x86/kernel/idt.c linux-libre-4.16-gnu/arch/x86/kernel/idt.c
--- linux-libre-4.16-rc7-gnu/arch/x86/kernel/idt.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/x86/kernel/idt.c	2018-04-01 17:20:27.000000000 -0400
@@ -140,6 +140,9 @@ static const __initconst struct idt_data
 # ifdef CONFIG_IRQ_WORK
 	INTG(IRQ_WORK_VECTOR,		irq_work_interrupt),
 # endif
+#ifdef CONFIG_X86_UV
+	INTG(UV_BAU_MESSAGE,		uv_bau_message_intr1),
+#endif
 	INTG(SPURIOUS_APIC_VECTOR,	spurious_interrupt),
 	INTG(ERROR_APIC_VECTOR,		error_interrupt),
 #endif
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/x86/kernel/kvm.c linux-libre-4.16-gnu/arch/x86/kernel/kvm.c
--- linux-libre-4.16-rc7-gnu/arch/x86/kernel/kvm.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/x86/kernel/kvm.c	2018-04-01 17:20:27.000000000 -0400
@@ -546,7 +546,7 @@ static void __init kvm_guest_init(void)
 	}
 
 	if (kvm_para_has_feature(KVM_FEATURE_PV_TLB_FLUSH) &&
-	    !kvm_para_has_feature(KVM_FEATURE_STEAL_TIME))
+	    kvm_para_has_feature(KVM_FEATURE_STEAL_TIME))
 		pv_mmu_ops.flush_tlb_others = kvm_flush_tlb_others;
 
 	if (kvm_para_has_feature(KVM_FEATURE_PV_EOI))
@@ -635,7 +635,7 @@ static __init int kvm_setup_pv_tlb_flush
 	int cpu;
 
 	if (kvm_para_has_feature(KVM_FEATURE_PV_TLB_FLUSH) &&
-	    !kvm_para_has_feature(KVM_FEATURE_STEAL_TIME)) {
+	    kvm_para_has_feature(KVM_FEATURE_STEAL_TIME)) {
 		for_each_possible_cpu(cpu) {
 			zalloc_cpumask_var_node(per_cpu_ptr(&__pv_tlb_mask, cpu),
 				GFP_KERNEL, cpu_to_node(cpu));
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/x86/kvm/vmx.c linux-libre-4.16-gnu/arch/x86/kvm/vmx.c
--- linux-libre-4.16-rc7-gnu/arch/x86/kvm/vmx.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/x86/kvm/vmx.c	2018-04-01 17:20:27.000000000 -0400
@@ -10711,6 +10711,11 @@ static int prepare_vmcs02(struct kvm_vcp
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
 	u32 exec_control, vmcs12_exec_ctrl;
 
+	if (vmx->nested.dirty_vmcs12) {
+		prepare_vmcs02_full(vcpu, vmcs12, from_vmentry);
+		vmx->nested.dirty_vmcs12 = false;
+	}
+
 	/*
 	 * First, the fields that are shadowed.  This must be kept in sync
 	 * with vmx_shadow_fields.h.
@@ -10948,11 +10953,6 @@ static int prepare_vmcs02(struct kvm_vcp
 	/* Note: modifies VM_ENTRY/EXIT_CONTROLS and GUEST/HOST_IA32_EFER */
 	vmx_set_efer(vcpu, vcpu->arch.efer);
 
-	if (vmx->nested.dirty_vmcs12) {
-		prepare_vmcs02_full(vcpu, vmcs12, from_vmentry);
-		vmx->nested.dirty_vmcs12 = false;
-	}
-
 	/* Shadow page tables on either EPT or shadow page tables. */
 	if (nested_vmx_load_cr3(vcpu, vmcs12->guest_cr3, nested_cpu_has_ept(vmcs12),
 				entry_failure_code))
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/x86/platform/uv/tlb_uv.c linux-libre-4.16-gnu/arch/x86/platform/uv/tlb_uv.c
--- linux-libre-4.16-rc7-gnu/arch/x86/platform/uv/tlb_uv.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/x86/platform/uv/tlb_uv.c	2018-04-01 17:20:27.000000000 -0400
@@ -2255,8 +2255,6 @@ static int __init uv_bau_init(void)
 			init_uvhub(uvhub, vector, uv_base_pnode);
 	}
 
-	alloc_intr_gate(vector, uv_bau_message_intr1);
-
 	for_each_possible_blade(uvhub) {
 		if (uv_blade_nr_possible_cpus(uvhub)) {
 			unsigned long val;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/arch/x86/purgatory/Makefile linux-libre-4.16-gnu/arch/x86/purgatory/Makefile
--- linux-libre-4.16-rc7-gnu/arch/x86/purgatory/Makefile	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/arch/x86/purgatory/Makefile	2018-04-01 17:20:27.000000000 -0400
@@ -16,7 +16,7 @@ KCOV_INSTRUMENT := n
 # in turn leaves some undefined symbols like __fentry__ in purgatory and not
 # sure how to relocate those. Like kexec-tools, use custom flags.
 
-KBUILD_CFLAGS := -fno-strict-aliasing -Wall -Wstrict-prototypes -fno-zero-initialized-in-bss -fno-builtin -ffreestanding -c -MD -Os -mcmodel=large
+KBUILD_CFLAGS := -fno-strict-aliasing -Wall -Wstrict-prototypes -fno-zero-initialized-in-bss -fno-builtin -ffreestanding -c -Os -mcmodel=large
 KBUILD_CFLAGS += -m$(BITS)
 KBUILD_CFLAGS += $(call cc-option,-fno-PIE)
 
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/Documentation/isdn/INTERFACE.CAPI linux-libre-4.16-gnu/Documentation/isdn/INTERFACE.CAPI
--- linux-libre-4.16-rc7-gnu/Documentation/isdn/INTERFACE.CAPI	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/Documentation/isdn/INTERFACE.CAPI	2018-04-01 17:20:27.000000000 -0400
@@ -18,7 +18,7 @@ corresponding hardware driver. Kernel CA
 directions between the application and the hardware driver.
 
 Format and semantics of CAPI messages are specified in the CAPI 2.0 standard.
-This standard is freely available from http://www.capi.org.
+This standard is freely available from https://www.capi.org.
 
 
 2. Driver and Device Registration
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/Documentation/isdn/README linux-libre-4.16-gnu/Documentation/isdn/README
--- linux-libre-4.16-rc7-gnu/Documentation/isdn/README	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/Documentation/isdn/README	2018-04-01 17:20:27.000000000 -0400
@@ -33,10 +33,10 @@ README for the ISDN-subsystem
      de.alt.comm.isdn4linux
 
   There is also a well maintained FAQ in English available at
-     http://www.mhessler.de/i4lfaq/
+     https://www.mhessler.de/i4lfaq/
   It can be viewed online, or downloaded in sgml/text/html format.
   The FAQ can also be viewed online at
-     http://www.isdn4linux.de/faq/
+     https://www.isdn4linux.de/faq/i4lfaq.html
   or downloaded from
      ftp://ftp.isdn4linux.de/pub/isdn4linux/FAQ/
 
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/Documentation/isdn/README.FAQ linux-libre-4.16-gnu/Documentation/isdn/README.FAQ
--- linux-libre-4.16-rc7-gnu/Documentation/isdn/README.FAQ	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/Documentation/isdn/README.FAQ	2018-04-01 17:20:27.000000000 -0400
@@ -8,9 +8,9 @@ You find it in:
 
 In case you just want to see the FAQ online, or download the newest version,
 you can have a look at my website:
-http://www.mhessler.de/i4lfaq/ (view + download)
+https://www.mhessler.de/i4lfaq/ (view + download)
 or:
-http://www.isdn4linux.de/faq/ (view)
+https://www.isdn4linux.de/faq/4lfaq.html (view)
 
 As the extension tells, the FAQ is in SGML format, and you can convert it
 into text/html/... format by using the sgml2txt/sgml2html/... tools.
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/Documentation/isdn/README.gigaset linux-libre-4.16-gnu/Documentation/isdn/README.gigaset
--- linux-libre-4.16-rc7-gnu/Documentation/isdn/README.gigaset	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/Documentation/isdn/README.gigaset	2018-04-01 17:20:27.000000000 -0400
@@ -29,8 +29,9 @@ GigaSet 307x Device Driver
         T-Com Sinus 721 data
         Chicago 390 USB (KPN)
 
-     See also http://www.erbze.info/sinus_gigaset.htm and
-              http://gigaset307x.sourceforge.net/
+     See also http://www.erbze.info/sinus_gigaset.htm
+       (archived at https://web.archive.org/web/20100717020421/http://www.erbze.info:80/sinus_gigaset.htm ) and
+	http://gigaset307x.sourceforge.net/
 
      We had also reports from users of Gigaset M105 who could use the drivers
      with SX 100 and CX 100 ISDN bases (only in unimodem mode, see section 2.5.)
@@ -52,7 +53,7 @@ GigaSet 307x Device Driver
      to use CAPI 2.0 or ISDN4Linux for ISDN connections (voice or data).
 
      There are some user space tools available at
-     http://sourceforge.net/projects/gigaset307x/
+     https://sourceforge.net/projects/gigaset307x/
      which provide access to additional device specific functions like SMS,
      phonebook or call journal.
 
@@ -202,7 +203,7 @@ GigaSet 307x Device Driver
      You can use some configuration tool of your distribution to configure this
      "modem" or configure pppd/wvdial manually. There are some example ppp
      configuration files and chat scripts in the gigaset-VERSION/ppp directory
-     in the driver packages from http://sourceforge.net/projects/gigaset307x/.
+     in the driver packages from https://sourceforge.net/projects/gigaset307x/.
      Please note that the USB drivers are not able to change the state of the
      control lines. This means you must use "Stupid Mode" if you are using
      wvdial or you should use the nocrtscts option of pppd.
@@ -361,7 +362,7 @@ GigaSet 307x Device Driver
      ---------------------------
      If you can't solve problems with the driver on your own, feel free to
      use one of the forums, bug trackers, or mailing lists on
-         http://sourceforge.net/projects/gigaset307x
+         https://sourceforge.net/projects/gigaset307x
      or write an electronic mail to the maintainers.
 
      Try to provide as much information as possible, such as
@@ -391,11 +392,12 @@ GigaSet 307x Device Driver
 4.   Links, other software
      ---------------------
      - Sourceforge project developing this driver and associated tools
-         http://sourceforge.net/projects/gigaset307x
+         https://sourceforge.net/projects/gigaset307x
      - Yahoo! Group on the Siemens Gigaset family of devices
-         http://de.groups.yahoo.com/group/Siemens-Gigaset
+         https://de.groups.yahoo.com/group/Siemens-Gigaset
      - Siemens Gigaset/T-Sinus compatibility table
          http://www.erbze.info/sinus_gigaset.htm
+	    (archived at https://web.archive.org/web/20100717020421/http://www.erbze.info:80/sinus_gigaset.htm )
 
 
 5.   Credits
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/atm/iphase.c linux-libre-4.16-gnu/drivers/atm/iphase.c
--- linux-libre-4.16-rc7-gnu/drivers/atm/iphase.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/atm/iphase.c	2018-04-01 17:20:27.000000000 -0400
@@ -3147,7 +3147,7 @@ static int ia_proc_read(struct atm_dev *
                            "  Size of Tx Buffer  :  %u\n"
                            "  Number of Rx Buffer:  %u\n"
                            "  Size of Rx Buffer  :  %u\n"
-                           "  Packets Receiverd  :  %u\n"
+                           "  Packets Received   :  %u\n"
                            "  Packets Transmitted:  %u\n"
                            "  Cells Received     :  %u\n"
                            "  Cells Transmitted  :  %u\n"
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c linux-libre-4.16-gnu/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
--- linux-libre-4.16-rc7-gnu/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c	2018-04-01 17:20:27.000000000 -0400
@@ -821,13 +821,13 @@ static int create_queue_cpsch(struct dev
 		pr_warn("Can't create new usermode queue because %d queues were already created\n",
 				dqm->total_queue_count);
 		retval = -EPERM;
-		goto out;
+		goto out_unlock;
 	}
 
 	if (q->properties.type == KFD_QUEUE_TYPE_SDMA) {
 		retval = allocate_sdma_queue(dqm, &q->sdma_id);
 		if (retval)
-			goto out;
+			goto out_unlock;
 		q->properties.sdma_queue_id =
 			q->sdma_id / CIK_SDMA_QUEUES_PER_ENGINE;
 		q->properties.sdma_engine_id =
@@ -838,7 +838,7 @@ static int create_queue_cpsch(struct dev
 
 	if (!mqd) {
 		retval = -ENOMEM;
-		goto out;
+		goto out_deallocate_sdma_queue;
 	}
 
 	dqm->asic_ops.init_sdma_vm(dqm, q, qpd);
@@ -848,7 +848,7 @@ static int create_queue_cpsch(struct dev
 	retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj,
 				&q->gart_mqd_addr, &q->properties);
 	if (retval)
-		goto out;
+		goto out_deallocate_sdma_queue;
 
 	list_add(&q->list, &qpd->queues_list);
 	qpd->queue_count++;
@@ -869,7 +869,13 @@ static int create_queue_cpsch(struct dev
 	pr_debug("Total of %d queues are accountable so far\n",
 			dqm->total_queue_count);
 
-out:
+	mutex_unlock(&dqm->lock);
+	return retval;
+
+out_deallocate_sdma_queue:
+	if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
+		deallocate_sdma_queue(dqm, q->sdma_id);
+out_unlock:
 	mutex_unlock(&dqm->lock);
 	return retval;
 }
@@ -1188,8 +1194,10 @@ static int process_termination_cpsch(str
 
 	/* Clear all user mode queues */
 	list_for_each_entry(q, &qpd->queues_list, list) {
-		if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
+		if (q->properties.type == KFD_QUEUE_TYPE_SDMA) {
 			dqm->sdma_queue_count--;
+			deallocate_sdma_queue(dqm, q->sdma_id);
+		}
 
 		if (q->properties.is_active)
 			dqm->queue_count--;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c linux-libre-4.16-gnu/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c
--- linux-libre-4.16-rc7-gnu/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c	2018-04-01 17:20:27.000000000 -0400
@@ -188,8 +188,7 @@ static int pm_create_map_process(struct
 	packet->sh_mem_ape1_base = qpd->sh_mem_ape1_base;
 	packet->sh_mem_ape1_limit = qpd->sh_mem_ape1_limit;
 
-	/* TODO: scratch support */
-	packet->sh_hidden_private_base_vmid = 0;
+	packet->sh_hidden_private_base_vmid = qpd->sh_hidden_private_base;
 
 	packet->gds_addr_lo = lower_32_bits(qpd->gds_context_area);
 	packet->gds_addr_hi = upper_32_bits(qpd->gds_context_area);
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/gpu/drm/tegra/dc.c linux-libre-4.16-gnu/drivers/gpu/drm/tegra/dc.c
--- linux-libre-4.16-rc7-gnu/drivers/gpu/drm/tegra/dc.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/gpu/drm/tegra/dc.c	2018-04-01 17:20:27.000000000 -0400
@@ -2009,9 +2009,9 @@ static const struct tegra_dc_soc_info te
 	.coupled_pm = false,
 	.has_nvdisplay = false,
 	.num_primary_formats = ARRAY_SIZE(tegra124_primary_formats),
-	.primary_formats = tegra114_primary_formats,
+	.primary_formats = tegra124_primary_formats,
 	.num_overlay_formats = ARRAY_SIZE(tegra124_overlay_formats),
-	.overlay_formats = tegra114_overlay_formats,
+	.overlay_formats = tegra124_overlay_formats,
 };
 
 static const struct tegra_dc_soc_info tegra210_dc_soc_info = {
@@ -2160,7 +2160,7 @@ static int tegra_dc_couple(struct tegra_
 		struct device_link *link;
 		struct device *partner;
 
-		partner = driver_find_device(dc->dev->driver, NULL, 0,
+		partner = driver_find_device(dc->dev->driver, NULL, NULL,
 					     tegra_dc_match_by_pipe);
 		if (!partner)
 			return -EPROBE_DEFER;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/i2c/busses/i2c-stm32f7.c linux-libre-4.16-gnu/drivers/i2c/busses/i2c-stm32f7.c
--- linux-libre-4.16-rc7-gnu/drivers/i2c/busses/i2c-stm32f7.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/i2c/busses/i2c-stm32f7.c	2018-04-01 17:20:27.000000000 -0400
@@ -888,6 +888,11 @@ static int stm32f7_i2c_probe(struct plat
 	}
 
 	setup = of_device_get_match_data(&pdev->dev);
+	if (!setup) {
+		dev_err(&pdev->dev, "Can't get device data\n");
+		ret = -ENODEV;
+		goto clk_free;
+	}
 	i2c_dev->setup = *setup;
 
 	ret = device_property_read_u32(i2c_dev->dev, "i2c-scl-rising-time-ns",
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/infiniband/core/addr.c linux-libre-4.16-gnu/drivers/infiniband/core/addr.c
--- linux-libre-4.16-rc7-gnu/drivers/infiniband/core/addr.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/infiniband/core/addr.c	2018-04-01 17:20:27.000000000 -0400
@@ -207,6 +207,22 @@ int rdma_addr_size(struct sockaddr *addr
 }
 EXPORT_SYMBOL(rdma_addr_size);
 
+int rdma_addr_size_in6(struct sockaddr_in6 *addr)
+{
+	int ret = rdma_addr_size((struct sockaddr *) addr);
+
+	return ret <= sizeof(*addr) ? ret : 0;
+}
+EXPORT_SYMBOL(rdma_addr_size_in6);
+
+int rdma_addr_size_kss(struct __kernel_sockaddr_storage *addr)
+{
+	int ret = rdma_addr_size((struct sockaddr *) addr);
+
+	return ret <= sizeof(*addr) ? ret : 0;
+}
+EXPORT_SYMBOL(rdma_addr_size_kss);
+
 static struct rdma_addr_client self;
 
 void rdma_addr_register_client(struct rdma_addr_client *client)
@@ -586,6 +602,15 @@ static void process_one_req(struct work_
 	list_del(&req->list);
 	mutex_unlock(&lock);
 
+	/*
+	 * Although the work will normally have been canceled by the
+	 * workqueue, it can still be requeued as long as it is on the
+	 * req_list, so it could have been requeued before we grabbed &lock.
+	 * We need to cancel it after it is removed from req_list to really be
+	 * sure it is safe to free.
+	 */
+	cancel_delayed_work(&req->work);
+
 	req->callback(req->status, (struct sockaddr *)&req->src_addr,
 		req->addr, req->context);
 	put_client(req->client);
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/infiniband/core/device.c linux-libre-4.16-gnu/drivers/infiniband/core/device.c
--- linux-libre-4.16-rc7-gnu/drivers/infiniband/core/device.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/infiniband/core/device.c	2018-04-01 17:20:27.000000000 -0400
@@ -290,6 +290,7 @@ void ib_dealloc_device(struct ib_device
 {
 	WARN_ON(device->reg_state != IB_DEV_UNREGISTERED &&
 		device->reg_state != IB_DEV_UNINITIALIZED);
+	rdma_restrack_clean(&device->res);
 	put_device(&device->dev);
 }
 EXPORT_SYMBOL(ib_dealloc_device);
@@ -600,8 +601,6 @@ void ib_unregister_device(struct ib_devi
 	}
 	up_read(&lists_rwsem);
 
-	rdma_restrack_clean(&device->res);
-
 	ib_device_unregister_rdmacg(device);
 	ib_device_unregister_sysfs(device);
 
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/infiniband/core/ucma.c linux-libre-4.16-gnu/drivers/infiniband/core/ucma.c
--- linux-libre-4.16-rc7-gnu/drivers/infiniband/core/ucma.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/infiniband/core/ucma.c	2018-04-01 17:20:27.000000000 -0400
@@ -632,6 +632,9 @@ static ssize_t ucma_bind_ip(struct ucma_
 	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
 		return -EFAULT;
 
+	if (!rdma_addr_size_in6(&cmd.addr))
+		return -EINVAL;
+
 	ctx = ucma_get_ctx(file, cmd.id);
 	if (IS_ERR(ctx))
 		return PTR_ERR(ctx);
@@ -645,22 +648,21 @@ static ssize_t ucma_bind(struct ucma_fil
 			 int in_len, int out_len)
 {
 	struct rdma_ucm_bind cmd;
-	struct sockaddr *addr;
 	struct ucma_context *ctx;
 	int ret;
 
 	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
 		return -EFAULT;
 
-	addr = (struct sockaddr *) &cmd.addr;
-	if (cmd.reserved || !cmd.addr_size || (cmd.addr_size != rdma_addr_size(addr)))
+	if (cmd.reserved || !cmd.addr_size ||
+	    cmd.addr_size != rdma_addr_size_kss(&cmd.addr))
 		return -EINVAL;
 
 	ctx = ucma_get_ctx(file, cmd.id);
 	if (IS_ERR(ctx))
 		return PTR_ERR(ctx);
 
-	ret = rdma_bind_addr(ctx->cm_id, addr);
+	ret = rdma_bind_addr(ctx->cm_id, (struct sockaddr *) &cmd.addr);
 	ucma_put_ctx(ctx);
 	return ret;
 }
@@ -670,23 +672,22 @@ static ssize_t ucma_resolve_ip(struct uc
 			       int in_len, int out_len)
 {
 	struct rdma_ucm_resolve_ip cmd;
-	struct sockaddr *src, *dst;
 	struct ucma_context *ctx;
 	int ret;
 
 	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
 		return -EFAULT;
 
-	src = (struct sockaddr *) &cmd.src_addr;
-	dst = (struct sockaddr *) &cmd.dst_addr;
-	if (!rdma_addr_size(src) || !rdma_addr_size(dst))
+	if (!rdma_addr_size_in6(&cmd.src_addr) ||
+	    !rdma_addr_size_in6(&cmd.dst_addr))
 		return -EINVAL;
 
 	ctx = ucma_get_ctx(file, cmd.id);
 	if (IS_ERR(ctx))
 		return PTR_ERR(ctx);
 
-	ret = rdma_resolve_addr(ctx->cm_id, src, dst, cmd.timeout_ms);
+	ret = rdma_resolve_addr(ctx->cm_id, (struct sockaddr *) &cmd.src_addr,
+				(struct sockaddr *) &cmd.dst_addr, cmd.timeout_ms);
 	ucma_put_ctx(ctx);
 	return ret;
 }
@@ -696,24 +697,23 @@ static ssize_t ucma_resolve_addr(struct
 				 int in_len, int out_len)
 {
 	struct rdma_ucm_resolve_addr cmd;
-	struct sockaddr *src, *dst;
 	struct ucma_context *ctx;
 	int ret;
 
 	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
 		return -EFAULT;
 
-	src = (struct sockaddr *) &cmd.src_addr;
-	dst = (struct sockaddr *) &cmd.dst_addr;
-	if (cmd.reserved || (cmd.src_size && (cmd.src_size != rdma_addr_size(src))) ||
-	    !cmd.dst_size || (cmd.dst_size != rdma_addr_size(dst)))
+	if (cmd.reserved ||
+	    (cmd.src_size && (cmd.src_size != rdma_addr_size_kss(&cmd.src_addr))) ||
+	    !cmd.dst_size || (cmd.dst_size != rdma_addr_size_kss(&cmd.dst_addr)))
 		return -EINVAL;
 
 	ctx = ucma_get_ctx(file, cmd.id);
 	if (IS_ERR(ctx))
 		return PTR_ERR(ctx);
 
-	ret = rdma_resolve_addr(ctx->cm_id, src, dst, cmd.timeout_ms);
+	ret = rdma_resolve_addr(ctx->cm_id, (struct sockaddr *) &cmd.src_addr,
+				(struct sockaddr *) &cmd.dst_addr, cmd.timeout_ms);
 	ucma_put_ctx(ctx);
 	return ret;
 }
@@ -1166,6 +1166,11 @@ static ssize_t ucma_init_qp_attr(struct
 	if (IS_ERR(ctx))
 		return PTR_ERR(ctx);
 
+	if (!ctx->cm_id->device) {
+		ret = -EINVAL;
+		goto out;
+	}
+
 	resp.qp_attr_mask = 0;
 	memset(&qp_attr, 0, sizeof qp_attr);
 	qp_attr.qp_state = cmd.qp_state;
@@ -1307,7 +1312,7 @@ static ssize_t ucma_set_option(struct uc
 	if (IS_ERR(ctx))
 		return PTR_ERR(ctx);
 
-	if (unlikely(cmd.optval > KMALLOC_MAX_SIZE))
+	if (unlikely(cmd.optlen > KMALLOC_MAX_SIZE))
 		return -EINVAL;
 
 	optval = memdup_user((void __user *) (unsigned long) cmd.optval,
@@ -1331,7 +1336,7 @@ static ssize_t ucma_notify(struct ucma_f
 {
 	struct rdma_ucm_notify cmd;
 	struct ucma_context *ctx;
-	int ret;
+	int ret = -EINVAL;
 
 	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
 		return -EFAULT;
@@ -1340,7 +1345,9 @@ static ssize_t ucma_notify(struct ucma_f
 	if (IS_ERR(ctx))
 		return PTR_ERR(ctx);
 
-	ret = rdma_notify(ctx->cm_id, (enum ib_event_type) cmd.event);
+	if (ctx->cm_id->device)
+		ret = rdma_notify(ctx->cm_id, (enum ib_event_type)cmd.event);
+
 	ucma_put_ctx(ctx);
 	return ret;
 }
@@ -1426,7 +1433,7 @@ static ssize_t ucma_join_ip_multicast(st
 	join_cmd.response = cmd.response;
 	join_cmd.uid = cmd.uid;
 	join_cmd.id = cmd.id;
-	join_cmd.addr_size = rdma_addr_size((struct sockaddr *) &cmd.addr);
+	join_cmd.addr_size = rdma_addr_size_in6(&cmd.addr);
 	if (!join_cmd.addr_size)
 		return -EINVAL;
 
@@ -1445,7 +1452,7 @@ static ssize_t ucma_join_multicast(struc
 	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
 		return -EFAULT;
 
-	if (!rdma_addr_size((struct sockaddr *)&cmd.addr))
+	if (!rdma_addr_size_kss(&cmd.addr))
 		return -EINVAL;
 
 	return ucma_process_join(file, &cmd, out_len);
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/infiniband/hw/hns/hns_roce_hw_v2.c linux-libre-4.16-gnu/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
--- linux-libre-4.16-rc7-gnu/drivers/infiniband/hw/hns/hns_roce_hw_v2.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/infiniband/hw/hns/hns_roce_hw_v2.c	2018-04-01 17:20:27.000000000 -0400
@@ -4383,7 +4383,7 @@ err_dma_alloc_buf:
 	eq->l0_dma = 0;
 
 	if (mhop_num == 1)
-		for (i -= i; i >= 0; i--)
+		for (i -= 1; i >= 0; i--)
 			dma_free_coherent(dev, buf_chk_sz, eq->buf[i],
 					  eq->buf_dma[i]);
 	else if (mhop_num == 2) {
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/infiniband/hw/mlx5/main.c linux-libre-4.16-gnu/drivers/infiniband/hw/mlx5/main.c
--- linux-libre-4.16-rc7-gnu/drivers/infiniband/hw/mlx5/main.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/infiniband/hw/mlx5/main.c	2018-04-01 17:20:27.000000000 -0400
@@ -3448,9 +3448,12 @@ static void destroy_umrc_res(struct mlx5
 	if (err)
 		mlx5_ib_warn(dev, "mr cache cleanup failed\n");
 
-	mlx5_ib_destroy_qp(dev->umrc.qp);
-	ib_free_cq(dev->umrc.cq);
-	ib_dealloc_pd(dev->umrc.pd);
+	if (dev->umrc.qp)
+		mlx5_ib_destroy_qp(dev->umrc.qp);
+	if (dev->umrc.cq)
+		ib_free_cq(dev->umrc.cq);
+	if (dev->umrc.pd)
+		ib_dealloc_pd(dev->umrc.pd);
 }
 
 enum {
@@ -3552,12 +3555,15 @@ static int create_umr_res(struct mlx5_ib
 
 error_4:
 	mlx5_ib_destroy_qp(qp);
+	dev->umrc.qp = NULL;
 
 error_3:
 	ib_free_cq(cq);
+	dev->umrc.cq = NULL;
 
 error_2:
 	ib_dealloc_pd(pd);
+	dev->umrc.pd = NULL;
 
 error_0:
 	kfree(attr);
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/infiniband/hw/mlx5/mr.c linux-libre-4.16-gnu/drivers/infiniband/hw/mlx5/mr.c
--- linux-libre-4.16-rc7-gnu/drivers/infiniband/hw/mlx5/mr.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/infiniband/hw/mlx5/mr.c	2018-04-01 17:20:27.000000000 -0400
@@ -739,6 +739,9 @@ int mlx5_mr_cache_cleanup(struct mlx5_ib
 {
 	int i;
 
+	if (!dev->cache.wq)
+		return 0;
+
 	dev->cache.stopped = 1;
 	flush_workqueue(dev->cache.wq);
 
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/infiniband/hw/qedr/main.c linux-libre-4.16-gnu/drivers/infiniband/hw/qedr/main.c
--- linux-libre-4.16-rc7-gnu/drivers/infiniband/hw/qedr/main.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/infiniband/hw/qedr/main.c	2018-04-01 17:20:27.000000000 -0400
@@ -833,7 +833,8 @@ static struct qedr_dev *qedr_add(struct
 
 	dev->num_cnq = dev->ops->rdma_get_min_cnq_msix(cdev);
 	if (!dev->num_cnq) {
-		DP_ERR(dev, "not enough CNQ resources.\n");
+		DP_ERR(dev, "Failed. At least one CNQ is required.\n");
+		rc = -ENOMEM;
 		goto init_err;
 	}
 
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/infiniband/hw/qedr/verbs.c linux-libre-4.16-gnu/drivers/infiniband/hw/qedr/verbs.c
--- linux-libre-4.16-rc7-gnu/drivers/infiniband/hw/qedr/verbs.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/infiniband/hw/qedr/verbs.c	2018-04-01 17:20:27.000000000 -0400
@@ -1841,14 +1841,15 @@ static void qedr_reset_qp_hwq_info(struc
 
 static int qedr_update_qp_state(struct qedr_dev *dev,
 				struct qedr_qp *qp,
+				enum qed_roce_qp_state cur_state,
 				enum qed_roce_qp_state new_state)
 {
 	int status = 0;
 
-	if (new_state == qp->state)
+	if (new_state == cur_state)
 		return 0;
 
-	switch (qp->state) {
+	switch (cur_state) {
 	case QED_ROCE_QP_STATE_RESET:
 		switch (new_state) {
 		case QED_ROCE_QP_STATE_INIT:
@@ -1955,6 +1956,7 @@ int qedr_modify_qp(struct ib_qp *ibqp, s
 	struct qedr_dev *dev = get_qedr_dev(&qp->dev->ibdev);
 	const struct ib_global_route *grh = rdma_ah_read_grh(&attr->ah_attr);
 	enum ib_qp_state old_qp_state, new_qp_state;
+	enum qed_roce_qp_state cur_state;
 	int rc = 0;
 
 	DP_DEBUG(dev, QEDR_MSG_QP,
@@ -2086,18 +2088,23 @@ int qedr_modify_qp(struct ib_qp *ibqp, s
 		SET_FIELD(qp_params.modify_flags,
 			  QED_ROCE_MODIFY_QP_VALID_ACK_TIMEOUT, 1);
 
-		qp_params.ack_timeout = attr->timeout;
-		if (attr->timeout) {
-			u32 temp;
-
-			temp = 4096 * (1UL << attr->timeout) / 1000 / 1000;
-			/* FW requires [msec] */
-			qp_params.ack_timeout = temp;
-		} else {
-			/* Infinite */
+		/* The received timeout value is an exponent used like this:
+		 *    "12.7.34 LOCAL ACK TIMEOUT
+		 *    Value representing the transport (ACK) timeout for use by
+		 *    the remote, expressed as: 4.096 * 2^timeout [usec]"
+		 * The FW expects timeout in msec so we need to divide the usec
+		 * result by 1000. We'll approximate 1000~2^10, and 4.096 ~ 2^2,
+		 * so we get: 2^2 * 2^timeout / 2^10 = 2^(timeout - 8).
+		 * The value of zero means infinite so we use a 'max_t' to make
+		 * sure that sub 1 msec values will be configured as 1 msec.
+		 */
+		if (attr->timeout)
+			qp_params.ack_timeout =
+					1 << max_t(int, attr->timeout - 8, 0);
+		else
 			qp_params.ack_timeout = 0;
-		}
 	}
+
 	if (attr_mask & IB_QP_RETRY_CNT) {
 		SET_FIELD(qp_params.modify_flags,
 			  QED_ROCE_MODIFY_QP_VALID_RETRY_CNT, 1);
@@ -2170,13 +2177,25 @@ int qedr_modify_qp(struct ib_qp *ibqp, s
 		qp->dest_qp_num = attr->dest_qp_num;
 	}
 
+	cur_state = qp->state;
+
+	/* Update the QP state before the actual ramrod to prevent a race with
+	 * fast path. Modifying the QP state to error will cause the device to
+	 * flush the CQEs and while polling the flushed CQEs will considered as
+	 * a potential issue if the QP isn't in error state.
+	 */
+	if ((attr_mask & IB_QP_STATE) && qp->qp_type != IB_QPT_GSI &&
+	    !udata && qp_params.new_state == QED_ROCE_QP_STATE_ERR)
+		qp->state = QED_ROCE_QP_STATE_ERR;
+
 	if (qp->qp_type != IB_QPT_GSI)
 		rc = dev->ops->rdma_modify_qp(dev->rdma_ctx,
 					      qp->qed_qp, &qp_params);
 
 	if (attr_mask & IB_QP_STATE) {
 		if ((qp->qp_type != IB_QPT_GSI) && (!udata))
-			rc = qedr_update_qp_state(dev, qp, qp_params.new_state);
+			rc = qedr_update_qp_state(dev, qp, cur_state,
+						  qp_params.new_state);
 		qp->state = qp_params.new_state;
 	}
 
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/md/dm.c linux-libre-4.16-gnu/drivers/md/dm.c
--- linux-libre-4.16-rc7-gnu/drivers/md/dm.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/md/dm.c	2018-04-01 17:20:27.000000000 -0400
@@ -466,7 +466,7 @@ static int dm_get_bdev_for_ioctl(struct
 {
 	struct dm_target *tgt;
 	struct dm_table *map;
-	int srcu_idx, r;
+	int srcu_idx, r, r2;
 
 retry:
 	r = -ENOTTY;
@@ -492,9 +492,11 @@ retry:
 		goto out;
 
 	bdgrab(*bdev);
-	r = blkdev_get(*bdev, *mode, _dm_claim_ptr);
-	if (r < 0)
+	r2 = blkdev_get(*bdev, *mode, _dm_claim_ptr);
+	if (r2 < 0) {
+		r = r2;
 		goto out;
+	}
 
 	dm_put_live_table(md, srcu_idx);
 	return r;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/md/dm-mpath.c linux-libre-4.16-gnu/drivers/md/dm-mpath.c
--- linux-libre-4.16-rc7-gnu/drivers/md/dm-mpath.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/md/dm-mpath.c	2018-04-01 17:20:27.000000000 -0400
@@ -887,7 +887,7 @@ static struct pgpath *parse_path(struct
 
 	q = bdev_get_queue(p->path.dev->bdev);
 	attached_handler_name = scsi_dh_attached_handler_name(q, GFP_KERNEL);
-	if (attached_handler_name) {
+	if (attached_handler_name || m->hw_handler_name) {
 		INIT_DELAYED_WORK(&p->activate_path, activate_path_work);
 		r = setup_scsi_dh(p->path.dev->bdev, m, attached_handler_name, &ti->error);
 		if (r) {
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/mtd/chips/jedec_probe.c linux-libre-4.16-gnu/drivers/mtd/chips/jedec_probe.c
--- linux-libre-4.16-rc7-gnu/drivers/mtd/chips/jedec_probe.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/mtd/chips/jedec_probe.c	2018-04-01 17:20:27.000000000 -0400
@@ -1889,6 +1889,8 @@ static inline u32 jedec_read_mfr(struct
 	do {
 		uint32_t ofs = cfi_build_cmd_addr(0 + (bank << 8), map, cfi);
 		mask = (1 << (cfi->device_type * 8)) - 1;
+		if (ofs >= map->size)
+			return 0;
 		result = map_read(map, base + ofs);
 		bank++;
 	} while ((result.x[0] & mask) == CFI_MFR_CONTINUATION);
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/mtd/nand/atmel/pmecc.c linux-libre-4.16-gnu/drivers/mtd/nand/atmel/pmecc.c
--- linux-libre-4.16-rc7-gnu/drivers/mtd/nand/atmel/pmecc.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/mtd/nand/atmel/pmecc.c	2018-04-01 17:20:27.000000000 -0400
@@ -426,7 +426,7 @@ static int get_strength(struct atmel_pme
 
 static int get_sectorsize(struct atmel_pmecc_user *user)
 {
-	return user->cache.cfg & PMECC_LOOKUP_TABLE_SIZE_1024 ? 1024 : 512;
+	return user->cache.cfg & PMECC_CFG_SECTOR1024 ? 1024 : 512;
 }
 
 static void atmel_pmecc_gen_syndrome(struct atmel_pmecc_user *user, int sector)
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/bonding/bond_main.c linux-libre-4.16-gnu/drivers/net/bonding/bond_main.c
--- linux-libre-4.16-rc7-gnu/drivers/net/bonding/bond_main.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/bonding/bond_main.c	2018-04-01 17:20:27.000000000 -0400
@@ -1528,39 +1528,6 @@ int bond_enslave(struct net_device *bond
 			goto err_close;
 	}
 
-	/* If the mode uses primary, then the following is handled by
-	 * bond_change_active_slave().
-	 */
-	if (!bond_uses_primary(bond)) {
-		/* set promiscuity level to new slave */
-		if (bond_dev->flags & IFF_PROMISC) {
-			res = dev_set_promiscuity(slave_dev, 1);
-			if (res)
-				goto err_close;
-		}
-
-		/* set allmulti level to new slave */
-		if (bond_dev->flags & IFF_ALLMULTI) {
-			res = dev_set_allmulti(slave_dev, 1);
-			if (res)
-				goto err_close;
-		}
-
-		netif_addr_lock_bh(bond_dev);
-
-		dev_mc_sync_multiple(slave_dev, bond_dev);
-		dev_uc_sync_multiple(slave_dev, bond_dev);
-
-		netif_addr_unlock_bh(bond_dev);
-	}
-
-	if (BOND_MODE(bond) == BOND_MODE_8023AD) {
-		/* add lacpdu mc addr to mc list */
-		u8 lacpdu_multicast[ETH_ALEN] = MULTICAST_LACPDU_ADDR;
-
-		dev_mc_add(slave_dev, lacpdu_multicast);
-	}
-
 	res = vlan_vids_add_by_dev(slave_dev, bond_dev);
 	if (res) {
 		netdev_err(bond_dev, "Couldn't add bond vlan ids to %s\n",
@@ -1725,6 +1692,40 @@ int bond_enslave(struct net_device *bond
 		goto err_upper_unlink;
 	}
 
+	/* If the mode uses primary, then the following is handled by
+	 * bond_change_active_slave().
+	 */
+	if (!bond_uses_primary(bond)) {
+		/* set promiscuity level to new slave */
+		if (bond_dev->flags & IFF_PROMISC) {
+			res = dev_set_promiscuity(slave_dev, 1);
+			if (res)
+				goto err_sysfs_del;
+		}
+
+		/* set allmulti level to new slave */
+		if (bond_dev->flags & IFF_ALLMULTI) {
+			res = dev_set_allmulti(slave_dev, 1);
+			if (res) {
+				if (bond_dev->flags & IFF_PROMISC)
+					dev_set_promiscuity(slave_dev, -1);
+				goto err_sysfs_del;
+			}
+		}
+
+		netif_addr_lock_bh(bond_dev);
+		dev_mc_sync_multiple(slave_dev, bond_dev);
+		dev_uc_sync_multiple(slave_dev, bond_dev);
+		netif_addr_unlock_bh(bond_dev);
+
+		if (BOND_MODE(bond) == BOND_MODE_8023AD) {
+			/* add lacpdu mc addr to mc list */
+			u8 lacpdu_multicast[ETH_ALEN] = MULTICAST_LACPDU_ADDR;
+
+			dev_mc_add(slave_dev, lacpdu_multicast);
+		}
+	}
+
 	bond->slave_cnt++;
 	bond_compute_features(bond);
 	bond_set_carrier(bond);
@@ -1748,6 +1749,9 @@ int bond_enslave(struct net_device *bond
 	return 0;
 
 /* Undo stages on error */
+err_sysfs_del:
+	bond_sysfs_slave_del(new_slave);
+
 err_upper_unlink:
 	bond_upper_dev_unlink(bond, new_slave);
 
@@ -1755,9 +1759,6 @@ err_unregister:
 	netdev_rx_handler_unregister(slave_dev);
 
 err_detach:
-	if (!bond_uses_primary(bond))
-		bond_hw_addr_flush(bond_dev, slave_dev);
-
 	vlan_vids_del_by_dev(slave_dev, bond_dev);
 	if (rcu_access_pointer(bond->primary_slave) == new_slave)
 		RCU_INIT_POINTER(bond->primary_slave, NULL);
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/dsa/mt7530.c linux-libre-4.16-gnu/drivers/net/dsa/mt7530.c
--- linux-libre-4.16-rc7-gnu/drivers/net/dsa/mt7530.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/dsa/mt7530.c	2018-04-01 17:20:27.000000000 -0400
@@ -1409,6 +1409,7 @@ static const struct of_device_id mt7530_
 	{ .compatible = "mediatek,mt7530" },
 	{ /* sentinel */ },
 };
+MODULE_DEVICE_TABLE(of, mt7530_of_match);
 
 static struct mdio_driver mt7530_mdio_driver = {
 	.probe  = mt7530_probe,
@@ -1424,4 +1425,3 @@ mdio_module_driver(mt7530_mdio_driver);
 MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
 MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch");
 MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:mediatek-mt7530");
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/ethernet/marvell/mvneta.c linux-libre-4.16-gnu/drivers/net/ethernet/marvell/mvneta.c
--- linux-libre-4.16-rc7-gnu/drivers/net/ethernet/marvell/mvneta.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/ethernet/marvell/mvneta.c	2018-04-01 17:20:27.000000000 -0400
@@ -1132,6 +1132,7 @@ static void mvneta_port_up(struct mvneta
 	}
 	mvreg_write(pp, MVNETA_TXQ_CMD, q_map);
 
+	q_map = 0;
 	/* Enable all initialized RXQs. */
 	for (queue = 0; queue < rxq_number; queue++) {
 		struct mvneta_rx_queue *rxq = &pp->rxqs[queue];
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c linux-libre-4.16-gnu/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c
--- linux-libre-4.16-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c	2018-04-01 17:20:27.000000000 -0400
@@ -156,57 +156,63 @@ static int mlx4_en_dcbnl_getnumtcs(struc
 static u8 mlx4_en_dcbnl_set_all(struct net_device *netdev)
 {
 	struct mlx4_en_priv *priv = netdev_priv(netdev);
+	struct mlx4_en_port_profile *prof = priv->prof;
 	struct mlx4_en_dev *mdev = priv->mdev;
+	u8 tx_pause, tx_ppp, rx_pause, rx_ppp;
 
 	if (!(priv->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
 		return 1;
 
 	if (priv->cee_config.pfc_state) {
 		int tc;
+		rx_ppp = prof->rx_ppp;
+		tx_ppp = prof->tx_ppp;
 
-		priv->prof->rx_pause = 0;
-		priv->prof->tx_pause = 0;
 		for (tc = 0; tc < CEE_DCBX_MAX_PRIO; tc++) {
 			u8 tc_mask = 1 << tc;
 
 			switch (priv->cee_config.dcb_pfc[tc]) {
 			case pfc_disabled:
-				priv->prof->tx_ppp &= ~tc_mask;
-				priv->prof->rx_ppp &= ~tc_mask;
+				tx_ppp &= ~tc_mask;
+				rx_ppp &= ~tc_mask;
 				break;
 			case pfc_enabled_full:
-				priv->prof->tx_ppp |= tc_mask;
-				priv->prof->rx_ppp |= tc_mask;
+				tx_ppp |= tc_mask;
+				rx_ppp |= tc_mask;
 				break;
 			case pfc_enabled_tx:
-				priv->prof->tx_ppp |= tc_mask;
-				priv->prof->rx_ppp &= ~tc_mask;
+				tx_ppp |= tc_mask;
+				rx_ppp &= ~tc_mask;
 				break;
 			case pfc_enabled_rx:
-				priv->prof->tx_ppp &= ~tc_mask;
-				priv->prof->rx_ppp |= tc_mask;
+				tx_ppp &= ~tc_mask;
+				rx_ppp |= tc_mask;
 				break;
 			default:
 				break;
 			}
 		}
-		en_dbg(DRV, priv, "Set pfc on\n");
+		rx_pause = !!(rx_ppp || tx_ppp) ? 0 : prof->rx_pause;
+		tx_pause = !!(rx_ppp || tx_ppp) ? 0 : prof->tx_pause;
 	} else {
-		priv->prof->rx_pause = 1;
-		priv->prof->tx_pause = 1;
-		en_dbg(DRV, priv, "Set pfc off\n");
+		rx_ppp = 0;
+		tx_ppp = 0;
+		rx_pause = prof->rx_pause;
+		tx_pause = prof->tx_pause;
 	}
 
 	if (mlx4_SET_PORT_general(mdev->dev, priv->port,
 				  priv->rx_skb_size + ETH_FCS_LEN,
-				  priv->prof->tx_pause,
-				  priv->prof->tx_ppp,
-				  priv->prof->rx_pause,
-				  priv->prof->rx_ppp)) {
+				  tx_pause, tx_ppp, rx_pause, rx_ppp)) {
 		en_err(priv, "Failed setting pause params\n");
 		return 1;
 	}
 
+	prof->tx_ppp = tx_ppp;
+	prof->rx_ppp = rx_ppp;
+	prof->tx_pause = tx_pause;
+	prof->rx_pause = rx_pause;
+
 	return 0;
 }
 
@@ -408,6 +414,7 @@ static int mlx4_en_dcbnl_ieee_setpfc(str
 	struct mlx4_en_priv *priv = netdev_priv(dev);
 	struct mlx4_en_port_profile *prof = priv->prof;
 	struct mlx4_en_dev *mdev = priv->mdev;
+	u32 tx_pause, tx_ppp, rx_pause, rx_ppp;
 	int err;
 
 	en_dbg(DRV, priv, "cap: 0x%x en: 0x%x mbc: 0x%x delay: %d\n",
@@ -416,23 +423,26 @@ static int mlx4_en_dcbnl_ieee_setpfc(str
 			pfc->mbc,
 			pfc->delay);
 
-	prof->rx_pause = !pfc->pfc_en;
-	prof->tx_pause = !pfc->pfc_en;
-	prof->rx_ppp = pfc->pfc_en;
-	prof->tx_ppp = pfc->pfc_en;
+	rx_pause = prof->rx_pause && !pfc->pfc_en;
+	tx_pause = prof->tx_pause && !pfc->pfc_en;
+	rx_ppp = pfc->pfc_en;
+	tx_ppp = pfc->pfc_en;
 
 	err = mlx4_SET_PORT_general(mdev->dev, priv->port,
 				    priv->rx_skb_size + ETH_FCS_LEN,
-				    prof->tx_pause,
-				    prof->tx_ppp,
-				    prof->rx_pause,
-				    prof->rx_ppp);
-	if (err)
+				    tx_pause, tx_ppp, rx_pause, rx_ppp);
+	if (err) {
 		en_err(priv, "Failed setting pause params\n");
-	else
-		mlx4_en_update_pfc_stats_bitmap(mdev->dev, &priv->stats_bitmap,
-						prof->rx_ppp, prof->rx_pause,
-						prof->tx_ppp, prof->tx_pause);
+		return err;
+	}
+
+	mlx4_en_update_pfc_stats_bitmap(mdev->dev, &priv->stats_bitmap,
+					rx_ppp, rx_pause, tx_ppp, tx_pause);
+
+	prof->tx_ppp = tx_ppp;
+	prof->rx_ppp = rx_ppp;
+	prof->rx_pause = rx_pause;
+	prof->tx_pause = tx_pause;
 
 	return err;
 }
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c linux-libre-4.16-gnu/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
--- linux-libre-4.16-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c	2018-04-01 17:20:27.000000000 -0400
@@ -1046,27 +1046,32 @@ static int mlx4_en_set_pauseparam(struct
 {
 	struct mlx4_en_priv *priv = netdev_priv(dev);
 	struct mlx4_en_dev *mdev = priv->mdev;
+	u8 tx_pause, tx_ppp, rx_pause, rx_ppp;
 	int err;
 
 	if (pause->autoneg)
 		return -EINVAL;
 
-	priv->prof->tx_pause = pause->tx_pause != 0;
-	priv->prof->rx_pause = pause->rx_pause != 0;
+	tx_pause = !!(pause->tx_pause);
+	rx_pause = !!(pause->rx_pause);
+	rx_ppp = priv->prof->rx_ppp && !(tx_pause || rx_pause);
+	tx_ppp = priv->prof->tx_ppp && !(tx_pause || rx_pause);
+
 	err = mlx4_SET_PORT_general(mdev->dev, priv->port,
 				    priv->rx_skb_size + ETH_FCS_LEN,
-				    priv->prof->tx_pause,
-				    priv->prof->tx_ppp,
-				    priv->prof->rx_pause,
-				    priv->prof->rx_ppp);
-	if (err)
-		en_err(priv, "Failed setting pause params\n");
-	else
-		mlx4_en_update_pfc_stats_bitmap(mdev->dev, &priv->stats_bitmap,
-						priv->prof->rx_ppp,
-						priv->prof->rx_pause,
-						priv->prof->tx_ppp,
-						priv->prof->tx_pause);
+				    tx_pause, tx_ppp, rx_pause, rx_ppp);
+	if (err) {
+		en_err(priv, "Failed setting pause params, err = %d\n", err);
+		return err;
+	}
+
+	mlx4_en_update_pfc_stats_bitmap(mdev->dev, &priv->stats_bitmap,
+					rx_ppp, rx_pause, tx_ppp, tx_pause);
+
+	priv->prof->tx_pause = tx_pause;
+	priv->prof->rx_pause = rx_pause;
+	priv->prof->tx_ppp = tx_ppp;
+	priv->prof->rx_ppp = rx_ppp;
 
 	return err;
 }
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/en_main.c linux-libre-4.16-gnu/drivers/net/ethernet/mellanox/mlx4/en_main.c
--- linux-libre-4.16-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/en_main.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/ethernet/mellanox/mlx4/en_main.c	2018-04-01 17:20:27.000000000 -0400
@@ -163,9 +163,9 @@ static void mlx4_en_get_profile(struct m
 		params->udp_rss = 0;
 	}
 	for (i = 1; i <= MLX4_MAX_PORTS; i++) {
-		params->prof[i].rx_pause = 1;
+		params->prof[i].rx_pause = !(pfcrx || pfctx);
 		params->prof[i].rx_ppp = pfcrx;
-		params->prof[i].tx_pause = 1;
+		params->prof[i].tx_pause = !(pfcrx || pfctx);
 		params->prof[i].tx_ppp = pfctx;
 		params->prof[i].tx_ring_size = MLX4_EN_DEF_TX_RING_SIZE;
 		params->prof[i].rx_ring_size = MLX4_EN_DEF_RX_RING_SIZE;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c linux-libre-4.16-gnu/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
--- linux-libre-4.16-rc7-gnu/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c	2018-04-01 17:20:27.000000000 -0400
@@ -5088,6 +5088,7 @@ static void rem_slave_fs_rule(struct mlx
 						 &tracker->res_tree[RES_FS_RULE]);
 					list_del(&fs_rule->com.list);
 					spin_unlock_irq(mlx4_tlock(dev));
+					kfree(fs_rule->mirr_mbox);
 					kfree(fs_rule);
 					state = 0;
 					break;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c linux-libre-4.16-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
--- linux-libre-4.16-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c	2018-04-01 17:20:27.000000000 -0400
@@ -477,6 +477,9 @@ static int mlx5e_get_coalesce(struct net
 	return mlx5e_ethtool_get_coalesce(priv, coal);
 }
 
+#define MLX5E_MAX_COAL_TIME		MLX5_MAX_CQ_PERIOD
+#define MLX5E_MAX_COAL_FRAMES		MLX5_MAX_CQ_COUNT
+
 static void
 mlx5e_set_priv_channels_coalesce(struct mlx5e_priv *priv, struct ethtool_coalesce *coal)
 {
@@ -511,6 +514,20 @@ int mlx5e_ethtool_set_coalesce(struct ml
 	if (!MLX5_CAP_GEN(mdev, cq_moderation))
 		return -EOPNOTSUPP;
 
+	if (coal->tx_coalesce_usecs > MLX5E_MAX_COAL_TIME ||
+	    coal->rx_coalesce_usecs > MLX5E_MAX_COAL_TIME) {
+		netdev_info(priv->netdev, "%s: maximum coalesce time supported is %lu usecs\n",
+			    __func__, MLX5E_MAX_COAL_TIME);
+		return -ERANGE;
+	}
+
+	if (coal->tx_max_coalesced_frames > MLX5E_MAX_COAL_FRAMES ||
+	    coal->rx_max_coalesced_frames > MLX5E_MAX_COAL_FRAMES) {
+		netdev_info(priv->netdev, "%s: maximum coalesced frames supported is %lu\n",
+			    __func__, MLX5E_MAX_COAL_FRAMES);
+		return -ERANGE;
+	}
+
 	mutex_lock(&priv->state_lock);
 	new_channels.params = priv->channels.params;
 
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_main.c linux-libre-4.16-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
--- linux-libre-4.16-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_main.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_main.c	2018-04-01 17:20:27.000000000 -0400
@@ -2572,6 +2572,9 @@ int mlx5e_open(struct net_device *netdev
 		mlx5_set_port_admin_status(priv->mdev, MLX5_PORT_UP);
 	mutex_unlock(&priv->state_lock);
 
+	if (mlx5e_vxlan_allowed(priv->mdev))
+		udp_tunnel_get_rx_info(netdev);
+
 	return err;
 }
 
@@ -4069,7 +4072,7 @@ static void mlx5e_set_netdev_dev_addr(st
 	}
 }
 
-#if IS_ENABLED(CONFIG_NET_SWITCHDEV) && IS_ENABLED(CONFIG_MLX5_ESWITCH)
+#if IS_ENABLED(CONFIG_MLX5_ESWITCH)
 static const struct switchdev_ops mlx5e_switchdev_ops = {
 	.switchdev_port_attr_get	= mlx5e_attr_get,
 };
@@ -4175,7 +4178,7 @@ static void mlx5e_build_nic_netdev(struc
 
 	mlx5e_set_netdev_dev_addr(netdev);
 
-#if IS_ENABLED(CONFIG_NET_SWITCHDEV) && IS_ENABLED(CONFIG_MLX5_ESWITCH)
+#if IS_ENABLED(CONFIG_MLX5_ESWITCH)
 	if (MLX5_VPORT_MANAGER(mdev))
 		netdev->switchdev_ops = &mlx5e_switchdev_ops;
 #endif
@@ -4327,12 +4330,6 @@ static void mlx5e_nic_enable(struct mlx5
 #ifdef CONFIG_MLX5_CORE_EN_DCB
 	mlx5e_dcbnl_init_app(priv);
 #endif
-	/* Device already registered: sync netdev system state */
-	if (mlx5e_vxlan_allowed(mdev)) {
-		rtnl_lock();
-		udp_tunnel_get_rx_info(netdev);
-		rtnl_unlock();
-	}
 
 	queue_work(priv->wq, &priv->set_rx_mode_work);
 
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c linux-libre-4.16-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
--- linux-libre-4.16-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c	2018-04-01 17:20:27.000000000 -0400
@@ -44,6 +44,11 @@
 #include "en_tc.h"
 #include "fs_core.h"
 
+#define MLX5E_REP_PARAMS_LOG_SQ_SIZE \
+	max(0x6, MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE)
+#define MLX5E_REP_PARAMS_LOG_RQ_SIZE \
+	max(0x6, MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE)
+
 static const char mlx5e_rep_driver_name[] = "mlx5e_rep";
 
 static void mlx5e_rep_get_drvinfo(struct net_device *dev,
@@ -209,7 +214,7 @@ static void mlx5e_sqs2vport_stop(struct
 
 static int mlx5e_sqs2vport_start(struct mlx5_eswitch *esw,
 				 struct mlx5_eswitch_rep *rep,
-				 u16 *sqns_array, int sqns_num)
+				 u32 *sqns_array, int sqns_num)
 {
 	struct mlx5_flow_handle *flow_rule;
 	struct mlx5e_rep_priv *rpriv;
@@ -255,9 +260,9 @@ int mlx5e_add_sqs_fwd_rules(struct mlx5e
 	struct mlx5e_channel *c;
 	int n, tc, num_sqs = 0;
 	int err = -ENOMEM;
-	u16 *sqs;
+	u32 *sqs;
 
-	sqs = kcalloc(priv->channels.num * priv->channels.params.num_tc, sizeof(u16), GFP_KERNEL);
+	sqs = kcalloc(priv->channels.num * priv->channels.params.num_tc, sizeof(*sqs), GFP_KERNEL);
 	if (!sqs)
 		goto out;
 
@@ -288,7 +293,7 @@ void mlx5e_remove_sqs_fwd_rules(struct m
 static void mlx5e_rep_neigh_update_init_interval(struct mlx5e_rep_priv *rpriv)
 {
 #if IS_ENABLED(CONFIG_IPV6)
-	unsigned long ipv6_interval = NEIGH_VAR(&ipv6_stub->nd_tbl->parms,
+	unsigned long ipv6_interval = NEIGH_VAR(&nd_tbl.parms,
 						DELAY_PROBE_TIME);
 #else
 	unsigned long ipv6_interval = ~0UL;
@@ -424,7 +429,7 @@ static int mlx5e_rep_netevent_event(stru
 	case NETEVENT_NEIGH_UPDATE:
 		n = ptr;
 #if IS_ENABLED(CONFIG_IPV6)
-		if (n->tbl != ipv6_stub->nd_tbl && n->tbl != &arp_tbl)
+		if (n->tbl != &nd_tbl && n->tbl != &arp_tbl)
 #else
 		if (n->tbl != &arp_tbl)
 #endif
@@ -472,7 +477,7 @@ static int mlx5e_rep_netevent_event(stru
 		 * done per device delay prob time parameter.
 		 */
 #if IS_ENABLED(CONFIG_IPV6)
-		if (!p->dev || (p->tbl != ipv6_stub->nd_tbl && p->tbl != &arp_tbl))
+		if (!p->dev || (p->tbl != &nd_tbl && p->tbl != &arp_tbl))
 #else
 		if (!p->dev || p->tbl != &arp_tbl)
 #endif
@@ -668,7 +673,6 @@ static int mlx5e_rep_open(struct net_dev
 	struct mlx5e_priv *priv = netdev_priv(dev);
 	struct mlx5e_rep_priv *rpriv = priv->ppriv;
 	struct mlx5_eswitch_rep *rep = rpriv->rep;
-	struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
 	int err;
 
 	mutex_lock(&priv->state_lock);
@@ -676,8 +680,9 @@ static int mlx5e_rep_open(struct net_dev
 	if (err)
 		goto unlock;
 
-	if (!mlx5_eswitch_set_vport_state(esw, rep->vport,
-					  MLX5_ESW_VPORT_ADMIN_STATE_UP))
+	if (!mlx5_modify_vport_admin_state(priv->mdev,
+			MLX5_QUERY_VPORT_STATE_IN_OP_MOD_ESW_VPORT,
+			rep->vport, MLX5_ESW_VPORT_ADMIN_STATE_UP))
 		netif_carrier_on(dev);
 
 unlock:
@@ -690,11 +695,12 @@ static int mlx5e_rep_close(struct net_de
 	struct mlx5e_priv *priv = netdev_priv(dev);
 	struct mlx5e_rep_priv *rpriv = priv->ppriv;
 	struct mlx5_eswitch_rep *rep = rpriv->rep;
-	struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
 	int ret;
 
 	mutex_lock(&priv->state_lock);
-	(void)mlx5_eswitch_set_vport_state(esw, rep->vport, MLX5_ESW_VPORT_ADMIN_STATE_DOWN);
+	mlx5_modify_vport_admin_state(priv->mdev,
+			MLX5_QUERY_VPORT_STATE_IN_OP_MOD_ESW_VPORT,
+			rep->vport, MLX5_ESW_VPORT_ADMIN_STATE_DOWN);
 	ret = mlx5e_close_locked(dev);
 	mutex_unlock(&priv->state_lock);
 	return ret;
@@ -877,9 +883,9 @@ static void mlx5e_build_rep_params(struc
 					 MLX5_CQ_PERIOD_MODE_START_FROM_CQE :
 					 MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
 
-	params->log_sq_size = MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE;
+	params->log_sq_size = MLX5E_REP_PARAMS_LOG_SQ_SIZE;
 	params->rq_wq_type  = MLX5_WQ_TYPE_LINKED_LIST;
-	params->log_rq_size = MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE;
+	params->log_rq_size = MLX5E_REP_PARAMS_LOG_RQ_SIZE;
 
 	params->rx_dim_enabled = MLX5_CAP_GEN(mdev, cq_moderation);
 	mlx5e_set_rx_cq_mode_params(params, cq_period_mode);
@@ -899,9 +905,7 @@ static void mlx5e_build_rep_netdev(struc
 
 	netdev->ethtool_ops	  = &mlx5e_rep_ethtool_ops;
 
-#ifdef CONFIG_NET_SWITCHDEV
 	netdev->switchdev_ops = &mlx5e_rep_switchdev_ops;
-#endif
 
 	netdev->features	 |= NETIF_F_VLAN_CHALLENGED | NETIF_F_HW_TC | NETIF_F_NETNS_LOCAL;
 	netdev->hw_features      |= NETIF_F_HW_TC;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c linux-libre-4.16-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
--- linux-libre-4.16-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c	2018-04-01 17:20:27.000000000 -0400
@@ -963,7 +963,7 @@ void mlx5e_tc_update_neigh_used_value(st
 		tbl = &arp_tbl;
 #if IS_ENABLED(CONFIG_IPV6)
 	else if (m_neigh->family == AF_INET6)
-		tbl = ipv6_stub->nd_tbl;
+		tbl = &nd_tbl;
 #endif
 	else
 		return;
@@ -2608,19 +2608,19 @@ int mlx5e_configure_flower(struct mlx5e_
 	if (err != -EAGAIN)
 		flow->flags |= MLX5E_TC_FLOW_OFFLOADED;
 
+	if (!(flow->flags & MLX5E_TC_FLOW_ESWITCH) ||
+	    !(flow->esw_attr->action & MLX5_FLOW_CONTEXT_ACTION_ENCAP))
+		kvfree(parse_attr);
+
 	err = rhashtable_insert_fast(&tc->ht, &flow->node,
 				     tc->ht_params);
-	if (err)
-		goto err_del_rule;
+	if (err) {
+		mlx5e_tc_del_flow(priv, flow);
+		kfree(flow);
+	}
 
-	if (flow->flags & MLX5E_TC_FLOW_ESWITCH &&
-	    !(flow->esw_attr->action & MLX5_FLOW_CONTEXT_ACTION_ENCAP))
-		kvfree(parse_attr);
 	return err;
 
-err_del_rule:
-	mlx5e_tc_del_flow(priv, flow);
-
 err_free:
 	kvfree(parse_attr);
 	kfree(flow);
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/Kconfig linux-libre-4.16-gnu/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
--- linux-libre-4.16-rc7-gnu/drivers/net/ethernet/mellanox/mlx5/core/Kconfig	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/ethernet/mellanox/mlx5/core/Kconfig	2018-04-01 17:20:27.000000000 -0400
@@ -46,7 +46,7 @@ config MLX5_MPFS
 
 config MLX5_ESWITCH
 	bool "Mellanox Technologies MLX5 SRIOV E-Switch support"
-	depends on MLX5_CORE_EN
+	depends on MLX5_CORE_EN && NET_SWITCHDEV
 	default y
 	---help---
 	  Mellanox Technologies Ethernet SRIOV E-Switch support in ConnectX NIC.
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c linux-libre-4.16-gnu/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
--- linux-libre-4.16-rc7-gnu/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c	2018-04-01 17:20:27.000000000 -0400
@@ -1380,6 +1380,55 @@ mlxsw_sp_ipip_entry_ol_up_event(struct m
 						  decap_fib_entry);
 }
 
+static int
+mlxsw_sp_rif_ipip_lb_op(struct mlxsw_sp_rif_ipip_lb *lb_rif,
+			struct mlxsw_sp_vr *ul_vr, bool enable)
+{
+	struct mlxsw_sp_rif_ipip_lb_config lb_cf = lb_rif->lb_config;
+	struct mlxsw_sp_rif *rif = &lb_rif->common;
+	struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;
+	char ritr_pl[MLXSW_REG_RITR_LEN];
+	u32 saddr4;
+
+	switch (lb_cf.ul_protocol) {
+	case MLXSW_SP_L3_PROTO_IPV4:
+		saddr4 = be32_to_cpu(lb_cf.saddr.addr4);
+		mlxsw_reg_ritr_pack(ritr_pl, enable, MLXSW_REG_RITR_LOOPBACK_IF,
+				    rif->rif_index, rif->vr_id, rif->dev->mtu);
+		mlxsw_reg_ritr_loopback_ipip4_pack(ritr_pl, lb_cf.lb_ipipt,
+			    MLXSW_REG_RITR_LOOPBACK_IPIP_OPTIONS_GRE_KEY_PRESET,
+			    ul_vr->id, saddr4, lb_cf.okey);
+		break;
+
+	case MLXSW_SP_L3_PROTO_IPV6:
+		return -EAFNOSUPPORT;
+	}
+
+	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
+}
+
+static int mlxsw_sp_netdevice_ipip_ol_update_mtu(struct mlxsw_sp *mlxsw_sp,
+						 struct net_device *ol_dev)
+{
+	struct mlxsw_sp_ipip_entry *ipip_entry;
+	struct mlxsw_sp_rif_ipip_lb *lb_rif;
+	struct mlxsw_sp_vr *ul_vr;
+	int err = 0;
+
+	ipip_entry = mlxsw_sp_ipip_entry_find_by_ol_dev(mlxsw_sp, ol_dev);
+	if (ipip_entry) {
+		lb_rif = ipip_entry->ol_lb;
+		ul_vr = &mlxsw_sp->router->vrs[lb_rif->ul_vr_id];
+		err = mlxsw_sp_rif_ipip_lb_op(lb_rif, ul_vr, true);
+		if (err)
+			goto out;
+		lb_rif->common.mtu = ol_dev->mtu;
+	}
+
+out:
+	return err;
+}
+
 static void mlxsw_sp_netdevice_ipip_ol_up_event(struct mlxsw_sp *mlxsw_sp,
 						struct net_device *ol_dev)
 {
@@ -1660,6 +1709,8 @@ int mlxsw_sp_netdevice_ipip_ol_event(str
 		extack = info->extack;
 		return mlxsw_sp_netdevice_ipip_ol_change_event(mlxsw_sp,
 							       ol_dev, extack);
+	case NETDEV_CHANGEMTU:
+		return mlxsw_sp_netdevice_ipip_ol_update_mtu(mlxsw_sp, ol_dev);
 	}
 	return 0;
 }
@@ -6844,33 +6895,6 @@ mlxsw_sp_rif_ipip_lb_setup(struct mlxsw_
 }
 
 static int
-mlxsw_sp_rif_ipip_lb_op(struct mlxsw_sp_rif_ipip_lb *lb_rif,
-			struct mlxsw_sp_vr *ul_vr, bool enable)
-{
-	struct mlxsw_sp_rif_ipip_lb_config lb_cf = lb_rif->lb_config;
-	struct mlxsw_sp_rif *rif = &lb_rif->common;
-	struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;
-	char ritr_pl[MLXSW_REG_RITR_LEN];
-	u32 saddr4;
-
-	switch (lb_cf.ul_protocol) {
-	case MLXSW_SP_L3_PROTO_IPV4:
-		saddr4 = be32_to_cpu(lb_cf.saddr.addr4);
-		mlxsw_reg_ritr_pack(ritr_pl, enable, MLXSW_REG_RITR_LOOPBACK_IF,
-				    rif->rif_index, rif->vr_id, rif->dev->mtu);
-		mlxsw_reg_ritr_loopback_ipip4_pack(ritr_pl, lb_cf.lb_ipipt,
-			    MLXSW_REG_RITR_LOOPBACK_IPIP_OPTIONS_GRE_KEY_PRESET,
-			    ul_vr->id, saddr4, lb_cf.okey);
-		break;
-
-	case MLXSW_SP_L3_PROTO_IPV6:
-		return -EAFNOSUPPORT;
-	}
-
-	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
-}
-
-static int
 mlxsw_sp_rif_ipip_lb_configure(struct mlxsw_sp_rif *rif)
 {
 	struct mlxsw_sp_rif_ipip_lb *lb_rif = mlxsw_sp_rif_ipip_lb_rif(rif);
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/ethernet/netronome/nfp/bpf/jit.c linux-libre-4.16-gnu/drivers/net/ethernet/netronome/nfp/bpf/jit.c
--- linux-libre-4.16-rc7-gnu/drivers/net/ethernet/netronome/nfp/bpf/jit.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/ethernet/netronome/nfp/bpf/jit.c	2018-04-01 17:20:27.000000000 -0400
@@ -74,7 +74,9 @@ nfp_meta_has_prev(struct nfp_prog *nfp_p
 
 static void nfp_prog_push(struct nfp_prog *nfp_prog, u64 insn)
 {
-	if (nfp_prog->__prog_alloc_len == nfp_prog->prog_len) {
+	if (nfp_prog->__prog_alloc_len / sizeof(u64) == nfp_prog->prog_len) {
+		pr_warn("instruction limit reached (%u NFP instructions)\n",
+			nfp_prog->prog_len);
 		nfp_prog->error = -ENOSPC;
 		return;
 	}
@@ -2463,6 +2465,8 @@ static int nfp_translate(struct nfp_prog
 		err = cb(nfp_prog, meta);
 		if (err)
 			return err;
+		if (nfp_prog->error)
+			return nfp_prog->error;
 
 		nfp_prog->n_translated++;
 	}
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/ethernet/qlogic/qede/qede_fp.c linux-libre-4.16-gnu/drivers/net/ethernet/qlogic/qede/qede_fp.c
--- linux-libre-4.16-rc7-gnu/drivers/net/ethernet/qlogic/qede/qede_fp.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/ethernet/qlogic/qede/qede_fp.c	2018-04-01 17:20:27.000000000 -0400
@@ -320,13 +320,11 @@ static inline void qede_update_tx_produc
 	barrier();
 	writel(txq->tx_db.raw, txq->doorbell_addr);
 
-	/* mmiowb is needed to synchronize doorbell writes from more than one
-	 * processor. It guarantees that the write arrives to the device before
-	 * the queue lock is released and another start_xmit is called (possibly
-	 * on another CPU). Without this barrier, the next doorbell can bypass
-	 * this doorbell. This is applicable to IA64/Altix systems.
+	/* Fence required to flush the write combined buffer, since another
+	 * CPU may write to the same doorbell address and data may be lost
+	 * due to relaxed order nature of write combined bar.
 	 */
-	mmiowb();
+	wmb();
 }
 
 static int qede_xdp_xmit(struct qede_dev *edev, struct qede_fastpath *fp,
@@ -1249,16 +1247,10 @@ static int qede_rx_process_cqe(struct qe
 
 	csum_flag = qede_check_csum(parse_flag);
 	if (unlikely(csum_flag == QEDE_CSUM_ERROR)) {
-		if (qede_pkt_is_ip_fragmented(fp_cqe, parse_flag)) {
+		if (qede_pkt_is_ip_fragmented(fp_cqe, parse_flag))
 			rxq->rx_ip_frags++;
-		} else {
-			DP_NOTICE(edev,
-				  "CQE has error, flags = %x, dropping incoming packet\n",
-				  parse_flag);
+		else
 			rxq->rx_hw_errors++;
-			qede_recycle_rx_bd_ring(rxq, fp_cqe->bd_num);
-			return 0;
-		}
 	}
 
 	/* Basic validation passed; Need to prepare an SKB. This would also
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/ethernet/realtek/r8169.c linux-libre-4.16-gnu/drivers/net/ethernet/realtek/r8169.c
--- linux-libre-4.16-rc7-gnu/drivers/net/ethernet/realtek/r8169.c	2018-03-25 22:58:18.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/ethernet/realtek/r8169.c	2018-04-01 21:29:35.000000000 -0400
@@ -8642,12 +8642,12 @@ static int rtl_init_one(struct pci_dev *
 	if (!tp->counters)
 		return -ENOMEM;
 
+	pci_set_drvdata(pdev, dev);
+
 	rc = register_netdev(dev);
 	if (rc < 0)
 		return rc;
 
-	pci_set_drvdata(pdev, dev);
-
 	netif_info(tp, probe, dev, "%s at 0x%p, %pM, XID %08x IRQ %d\n",
 		   rtl_chip_infos[chipset].name, ioaddr, dev->dev_addr,
 		   (u32)(RTL_R32(TxConfig) & 0x9cf0f8ff), pdev->irq);
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/hyperv/rndis_filter.c linux-libre-4.16-gnu/drivers/net/hyperv/rndis_filter.c
--- linux-libre-4.16-rc7-gnu/drivers/net/hyperv/rndis_filter.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/hyperv/rndis_filter.c	2018-04-01 17:20:27.000000000 -0400
@@ -858,7 +858,7 @@ static void rndis_set_multicast(struct w
 	if (flags & IFF_PROMISC) {
 		filter = NDIS_PACKET_TYPE_PROMISCUOUS;
 	} else {
-		if (flags & IFF_ALLMULTI)
+		if (!netdev_mc_empty(rdev->ndev) || (flags & IFF_ALLMULTI))
 			filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
 		if (flags & IFF_BROADCAST)
 			filter |= NDIS_PACKET_TYPE_BROADCAST;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/team/team.c linux-libre-4.16-gnu/drivers/net/team/team.c
--- linux-libre-4.16-rc7-gnu/drivers/net/team/team.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/team/team.c	2018-04-01 17:20:27.000000000 -0400
@@ -1197,11 +1197,6 @@ static int team_port_add(struct team *te
 		goto err_dev_open;
 	}
 
-	netif_addr_lock_bh(dev);
-	dev_uc_sync_multiple(port_dev, dev);
-	dev_mc_sync_multiple(port_dev, dev);
-	netif_addr_unlock_bh(dev);
-
 	err = vlan_vids_add_by_dev(port_dev, dev);
 	if (err) {
 		netdev_err(dev, "Failed to add vlan ids to device %s\n",
@@ -1241,6 +1236,11 @@ static int team_port_add(struct team *te
 		goto err_option_port_add;
 	}
 
+	netif_addr_lock_bh(dev);
+	dev_uc_sync_multiple(port_dev, dev);
+	dev_mc_sync_multiple(port_dev, dev);
+	netif_addr_unlock_bh(dev);
+
 	port->index = -1;
 	list_add_tail_rcu(&port->list, &team->port_list);
 	team_port_enable(team, port);
@@ -1265,8 +1265,6 @@ err_enable_netpoll:
 	vlan_vids_del_by_dev(port_dev, dev);
 
 err_vids_add:
-	dev_uc_unsync(port_dev, dev);
-	dev_mc_unsync(port_dev, dev);
 	dev_close(port_dev);
 
 err_dev_open:
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/usb/lan78xx.c linux-libre-4.16-gnu/drivers/net/usb/lan78xx.c
--- linux-libre-4.16-rc7-gnu/drivers/net/usb/lan78xx.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/usb/lan78xx.c	2018-04-01 17:20:27.000000000 -0400
@@ -2351,6 +2351,7 @@ static int lan78xx_reset(struct lan78xx_
 	u32 buf;
 	int ret = 0;
 	unsigned long timeout;
+	u8 sig;
 
 	ret = lan78xx_read_reg(dev, HW_CFG, &buf);
 	buf |= HW_CFG_LRST_;
@@ -2450,6 +2451,15 @@ static int lan78xx_reset(struct lan78xx_
 	/* LAN7801 only has RGMII mode */
 	if (dev->chipid == ID_REV_CHIP_ID_7801_)
 		buf &= ~MAC_CR_GMII_EN_;
+
+	if (dev->chipid == ID_REV_CHIP_ID_7800_) {
+		ret = lan78xx_read_raw_eeprom(dev, 0, 1, &sig);
+		if (!ret && sig != EEPROM_INDICATOR) {
+			/* Implies there is no external eeprom. Set mac speed */
+			netdev_info(dev->net, "No External EEPROM. Setting MAC Speed\n");
+			buf |= MAC_CR_AUTO_DUPLEX_ | MAC_CR_AUTO_SPEED_;
+		}
+	}
 	ret = lan78xx_write_reg(dev, MAC_CR, buf);
 
 	ret = lan78xx_read_reg(dev, MAC_TX, &buf);
@@ -2863,8 +2873,7 @@ static int lan78xx_bind(struct lan78xx_n
 	if (ret < 0) {
 		netdev_warn(dev->net,
 			    "lan78xx_setup_irq_domain() failed : %d", ret);
-		kfree(pdata);
-		return ret;
+		goto out1;
 	}
 
 	dev->net->hard_header_len += TX_OVERHEAD;
@@ -2872,14 +2881,32 @@ static int lan78xx_bind(struct lan78xx_n
 
 	/* Init all registers */
 	ret = lan78xx_reset(dev);
+	if (ret) {
+		netdev_warn(dev->net, "Registers INIT FAILED....");
+		goto out2;
+	}
 
 	ret = lan78xx_mdio_init(dev);
+	if (ret) {
+		netdev_warn(dev->net, "MDIO INIT FAILED.....");
+		goto out2;
+	}
 
 	dev->net->flags |= IFF_MULTICAST;
 
 	pdata->wol = WAKE_MAGIC;
 
 	return ret;
+
+out2:
+	lan78xx_remove_irq_domain(dev);
+
+out1:
+	netdev_warn(dev->net, "Bind routine FAILED");
+	cancel_work_sync(&pdata->set_multicast);
+	cancel_work_sync(&pdata->set_vlan);
+	kfree(pdata);
+	return ret;
 }
 
 static void lan78xx_unbind(struct lan78xx_net *dev, struct usb_interface *intf)
@@ -2891,6 +2918,8 @@ static void lan78xx_unbind(struct lan78x
 	lan78xx_remove_mdio(dev);
 
 	if (pdata) {
+		cancel_work_sync(&pdata->set_multicast);
+		cancel_work_sync(&pdata->set_vlan);
 		netif_dbg(dev, ifdown, dev->net, "free pdata");
 		kfree(pdata);
 		pdata = NULL;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/usb/qmi_wwan.c linux-libre-4.16-gnu/drivers/net/usb/qmi_wwan.c
--- linux-libre-4.16-rc7-gnu/drivers/net/usb/qmi_wwan.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/usb/qmi_wwan.c	2018-04-01 17:20:27.000000000 -0400
@@ -1104,6 +1104,9 @@ static const struct usb_device_id produc
 	{QMI_FIXED_INTF(0x0846, 0x68a2, 8)},
 	{QMI_FIXED_INTF(0x12d1, 0x140c, 1)},	/* Huawei E173 */
 	{QMI_FIXED_INTF(0x12d1, 0x14ac, 1)},	/* Huawei E1820 */
+	{QMI_FIXED_INTF(0x1435, 0xd181, 3)},	/* Wistron NeWeb D18Q1 */
+	{QMI_FIXED_INTF(0x1435, 0xd181, 4)},	/* Wistron NeWeb D18Q1 */
+	{QMI_FIXED_INTF(0x1435, 0xd181, 5)},	/* Wistron NeWeb D18Q1 */
 	{QMI_FIXED_INTF(0x16d8, 0x6003, 0)},	/* CMOTech 6003 */
 	{QMI_FIXED_INTF(0x16d8, 0x6007, 0)},	/* CMOTech CHE-628S */
 	{QMI_FIXED_INTF(0x16d8, 0x6008, 0)},	/* CMOTech CMU-301 */
@@ -1180,6 +1183,7 @@ static const struct usb_device_id produc
 	{QMI_FIXED_INTF(0x19d2, 0x2002, 4)},	/* ZTE (Vodafone) K3765-Z */
 	{QMI_FIXED_INTF(0x2001, 0x7e19, 4)},	/* D-Link DWM-221 B1 */
 	{QMI_FIXED_INTF(0x2001, 0x7e35, 4)},	/* D-Link DWM-222 */
+	{QMI_FIXED_INTF(0x2020, 0x2033, 4)},	/* BroadMobi BM806U */
 	{QMI_FIXED_INTF(0x0f3d, 0x68a2, 8)},    /* Sierra Wireless MC7700 */
 	{QMI_FIXED_INTF(0x114f, 0x68a2, 8)},    /* Sierra Wireless MC7750 */
 	{QMI_FIXED_INTF(0x1199, 0x68a2, 8)},	/* Sierra Wireless MC7710 in QMI mode */
@@ -1240,6 +1244,7 @@ static const struct usb_device_id produc
 	{QMI_FIXED_INTF(0x413c, 0x81b6, 8)},	/* Dell Wireless 5811e */
 	{QMI_FIXED_INTF(0x413c, 0x81b6, 10)},	/* Dell Wireless 5811e */
 	{QMI_FIXED_INTF(0x03f0, 0x4e1d, 8)},	/* HP lt4111 LTE/EV-DO/HSPA+ Gobi 4G Module */
+	{QMI_FIXED_INTF(0x03f0, 0x9d1d, 1)},	/* HP lt4120 Snapdragon X5 LTE */
 	{QMI_FIXED_INTF(0x22de, 0x9061, 3)},	/* WeTelecom WPD-600N */
 	{QMI_FIXED_INTF(0x1e0e, 0x9001, 5)},	/* SIMCom 7230E */
 	{QMI_QUIRK_SET_DTR(0x2c7c, 0x0125, 4)},	/* Quectel EC25, EC20 R2.0  Mini PCIe */
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/vrf.c linux-libre-4.16-gnu/drivers/net/vrf.c
--- linux-libre-4.16-rc7-gnu/drivers/net/vrf.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/vrf.c	2018-04-01 17:20:27.000000000 -0400
@@ -578,12 +578,13 @@ static int vrf_finish_output(struct net
 	if (!IS_ERR(neigh)) {
 		sock_confirm_neigh(skb, neigh);
 		ret = neigh_output(neigh, skb);
+		rcu_read_unlock_bh();
+		return ret;
 	}
 
 	rcu_read_unlock_bh();
 err:
-	if (unlikely(ret < 0))
-		vrf_tx_error(skb->dev, skb);
+	vrf_tx_error(skb->dev, skb);
 	return ret;
 }
 
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c linux-libre-4.16-gnu/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
--- linux-libre-4.16-rc7-gnu/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c	2018-04-01 17:20:27.000000000 -0400
@@ -6802,7 +6802,7 @@ static void brcmf_cfg80211_reg_notifier(
 		return;
 
 	/* ignore non-ISO3166 country codes */
-	for (i = 0; i < sizeof(req->alpha2); i++)
+	for (i = 0; i < 2; i++)
 		if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') {
 			brcmf_err("not an ISO3166 code (0x%02x 0x%02x)\n",
 				  req->alpha2[0], req->alpha2[1]);
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c linux-libre-4.16-gnu/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
--- linux-libre-4.16-rc7-gnu/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c	2018-04-01 17:20:27.000000000 -0400
@@ -75,6 +75,10 @@ static int brcmf_roamoff;
 module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR);
 MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine");
 
+static int brcmf_iapp_enable;
+module_param_named(iapp, brcmf_iapp_enable, int, 0);
+MODULE_PARM_DESC(iapp, "Enable partial support for the obsoleted Inter-Access Point Protocol");
+
 #ifdef DEBUG
 /* always succeed brcmf_bus_started() */
 static int brcmf_ignore_probe_fail;
@@ -441,6 +445,7 @@ struct brcmf_mp_device *brcmf_get_module
 	settings->feature_disable = brcmf_feature_disable;
 	settings->fcmode = brcmf_fcmode;
 	settings->roamoff = !!brcmf_roamoff;
+	settings->iapp = !!brcmf_iapp_enable;
 #ifdef DEBUG
 	settings->ignore_probe_fail = !!brcmf_ignore_probe_fail;
 #endif
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h linux-libre-4.16-gnu/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
--- linux-libre-4.16-rc7-gnu/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h	2018-04-01 17:20:27.000000000 -0400
@@ -58,6 +58,7 @@ struct brcmf_mp_device {
 	unsigned int	feature_disable;
 	int		fcmode;
 	bool		roamoff;
+	bool		iapp;
 	bool		ignore_probe_fail;
 	struct brcmfmac_pd_cc *country_codes;
 	union {
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c linux-libre-4.16-gnu/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
--- linux-libre-4.16-rc7-gnu/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c	2018-04-01 17:20:27.000000000 -0400
@@ -230,6 +230,37 @@ static void brcmf_netdev_set_multicast_l
 	schedule_work(&ifp->multicast_work);
 }
 
+/**
+ * brcmf_skb_is_iapp - checks if skb is an IAPP packet
+ *
+ * @skb: skb to check
+ */
+static bool brcmf_skb_is_iapp(struct sk_buff *skb)
+{
+	static const u8 iapp_l2_update_packet[6] __aligned(2) = {
+		0x00, 0x01, 0xaf, 0x81, 0x01, 0x00,
+	};
+	unsigned char *eth_data;
+#if !defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
+	const u16 *a, *b;
+#endif
+
+	if (skb->len - skb->mac_len != 6 ||
+	    !is_multicast_ether_addr(eth_hdr(skb)->h_dest))
+		return false;
+
+	eth_data = skb_mac_header(skb) + ETH_HLEN;
+#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
+	return !(((*(const u32 *)eth_data) ^ (*(const u32 *)iapp_l2_update_packet)) |
+		 ((*(const u16 *)(eth_data + 4)) ^ (*(const u16 *)(iapp_l2_update_packet + 4))));
+#else
+	a = (const u16 *)eth_data;
+	b = (const u16 *)iapp_l2_update_packet;
+
+	return !((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]));
+#endif
+}
+
 static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
 					   struct net_device *ndev)
 {
@@ -250,6 +281,23 @@ static netdev_tx_t brcmf_netdev_start_xm
 		goto done;
 	}
 
+	/* Some recent Broadcom's firmwares disassociate STA when they receive
+	 * an 802.11f ADD frame. This behavior can lead to a local DoS security
+	 * issue. Attacker may trigger disassociation of any STA by sending a
+	 * proper Ethernet frame to the wireless interface.
+	 *
+	 * Moreover this feature may break AP interfaces in some specific
+	 * setups. This applies e.g. to the bridge with hairpin mode enabled and
+	 * IFLA_BRPORT_MCAST_TO_UCAST set. IAPP packet generated by a firmware
+	 * will get passed back to the wireless interface and cause immediate
+	 * disassociation of a just-connected STA.
+	 */
+	if (!drvr->settings->iapp && brcmf_skb_is_iapp(skb)) {
+		dev_kfree_skb(skb);
+		ret = -EINVAL;
+		goto done;
+	}
+
 	/* Make sure there's enough writeable headroom */
 	if (skb_headroom(skb) < drvr->hdrlen || skb_header_cloned(skb)) {
 		head_delta = max_t(int, drvr->hdrlen - skb_headroom(skb), 0);
@@ -325,6 +373,15 @@ void brcmf_txflowblock_if(struct brcmf_i
 
 void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb)
 {
+	/* Most of Broadcom's firmwares send 802.11f ADD frame every time a new
+	 * STA connects to the AP interface. This is an obsoleted standard most
+	 * users don't use, so don't pass these frames up unless requested.
+	 */
+	if (!ifp->drvr->settings->iapp && brcmf_skb_is_iapp(skb)) {
+		brcmu_pkt_buf_free_skb(skb);
+		return;
+	}
+
 	if (skb->pkt_type == PACKET_MULTICAST)
 		ifp->ndev->stats.multicast++;
 
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/wireless/intel/iwlwifi/cfg/9000.c linux-libre-4.16-gnu/drivers/net/wireless/intel/iwlwifi/cfg/9000.c
--- linux-libre-4.16-rc7-gnu/drivers/net/wireless/intel/iwlwifi/cfg/9000.c	2018-03-25 23:01:06.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/wireless/intel/iwlwifi/cfg/9000.c	2018-04-01 21:32:11.000000000 -0400
@@ -53,6 +53,7 @@
 #include <linux/stringify.h>
 #include "iwl-config.h"
 #include "iwl-agn-hw.h"
+#include "fw/file.h"
 
 /* Highest firmware API version supported */
 #define IWL9000_UCODE_API_MAX	36
@@ -265,4 +266,65 @@ const struct iwl_cfg iwl9560_2ac_cfg_soc
 	.integrated = true,
 	.soc_latency = 5000,
 };
+
+const struct iwl_cfg iwl9460_2ac_cfg_shared_clk = {
+	.name = "Intel(R) Dual Band Wireless AC 9460",
+	.fw_name_pre = IWL9000A_FW_PRE,
+	.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
+	.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
+	IWL_DEVICE_9000,
+	.ht_params = &iwl9000_ht_params,
+	.nvm_ver = IWL9000_NVM_VERSION,
+	.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
+	.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
+	.integrated = true,
+	.soc_latency = 5000,
+	.extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK
+};
+
+const struct iwl_cfg iwl9461_2ac_cfg_shared_clk = {
+	.name = "Intel(R) Dual Band Wireless AC 9461",
+	.fw_name_pre = IWL9000A_FW_PRE,
+	.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
+	.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
+	IWL_DEVICE_9000,
+	.ht_params = &iwl9000_ht_params,
+	.nvm_ver = IWL9000_NVM_VERSION,
+	.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
+	.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
+	.integrated = true,
+	.soc_latency = 5000,
+	.extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK
+};
+
+const struct iwl_cfg iwl9462_2ac_cfg_shared_clk = {
+	.name = "Intel(R) Dual Band Wireless AC 9462",
+	.fw_name_pre = IWL9000A_FW_PRE,
+	.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
+	.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
+	IWL_DEVICE_9000,
+	.ht_params = &iwl9000_ht_params,
+	.nvm_ver = IWL9000_NVM_VERSION,
+	.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
+	.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
+	.integrated = true,
+	.soc_latency = 5000,
+	.extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK
+};
+
+const struct iwl_cfg iwl9560_2ac_cfg_shared_clk = {
+	.name = "Intel(R) Dual Band Wireless AC 9560",
+	.fw_name_pre = IWL9000A_FW_PRE,
+	.fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
+	.fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
+	IWL_DEVICE_9000,
+	.ht_params = &iwl9000_ht_params,
+	.nvm_ver = IWL9000_NVM_VERSION,
+	.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
+	.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
+	.integrated = true,
+	.soc_latency = 5000,
+	.extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK
+};
+
 /*(DEBLOBBED)*/
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/wireless/intel/iwlwifi/fw/file.h linux-libre-4.16-gnu/drivers/net/wireless/intel/iwlwifi/fw/file.h
--- linux-libre-4.16-rc7-gnu/drivers/net/wireless/intel/iwlwifi/fw/file.h	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/wireless/intel/iwlwifi/fw/file.h	2018-04-01 17:20:27.000000000 -0400
@@ -441,6 +441,7 @@ enum iwl_fw_phy_cfg {
 	FW_PHY_CFG_TX_CHAIN = 0xf << FW_PHY_CFG_TX_CHAIN_POS,
 	FW_PHY_CFG_RX_CHAIN_POS = 20,
 	FW_PHY_CFG_RX_CHAIN = 0xf << FW_PHY_CFG_RX_CHAIN_POS,
+	FW_PHY_CFG_SHARED_CLK = BIT(31),
 };
 
 #define IWL_UCODE_MAX_CS		1
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/wireless/intel/iwlwifi/iwl-config.h linux-libre-4.16-gnu/drivers/net/wireless/intel/iwlwifi/iwl-config.h
--- linux-libre-4.16-rc7-gnu/drivers/net/wireless/intel/iwlwifi/iwl-config.h	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/wireless/intel/iwlwifi/iwl-config.h	2018-04-01 17:20:27.000000000 -0400
@@ -398,6 +398,7 @@ struct iwl_cfg {
 	u8 ucode_api_max;
 	u8 ucode_api_min;
 	u32 min_umac_error_event_table;
+	u32 extra_phy_cfg_flags;
 };
 
 /*
@@ -477,6 +478,10 @@ extern const struct iwl_cfg iwl9460_2ac_
 extern const struct iwl_cfg iwl9461_2ac_cfg_soc;
 extern const struct iwl_cfg iwl9462_2ac_cfg_soc;
 extern const struct iwl_cfg iwl9560_2ac_cfg_soc;
+extern const struct iwl_cfg iwl9460_2ac_cfg_shared_clk;
+extern const struct iwl_cfg iwl9461_2ac_cfg_shared_clk;
+extern const struct iwl_cfg iwl9462_2ac_cfg_shared_clk;
+extern const struct iwl_cfg iwl9560_2ac_cfg_shared_clk;
 extern const struct iwl_cfg iwl22000_2ac_cfg_hr;
 extern const struct iwl_cfg iwl22000_2ac_cfg_hr_cdb;
 extern const struct iwl_cfg iwl22000_2ac_cfg_jf;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/wireless/intel/iwlwifi/mvm/fw.c linux-libre-4.16-gnu/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
--- linux-libre-4.16-rc7-gnu/drivers/net/wireless/intel/iwlwifi/mvm/fw.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/wireless/intel/iwlwifi/mvm/fw.c	2018-04-01 17:20:27.000000000 -0400
@@ -433,6 +433,10 @@ static int iwl_send_phy_cfg_cmd(struct i
 
 	/* Set parameters */
 	phy_cfg_cmd.phy_cfg = cpu_to_le32(iwl_mvm_get_phy_config(mvm));
+
+	/* set flags extra PHY configuration flags from the device's cfg */
+	phy_cfg_cmd.phy_cfg |= cpu_to_le32(mvm->cfg->extra_phy_cfg_flags);
+
 	phy_cfg_cmd.calib_control.event_trigger =
 		mvm->fw->default_calib[ucode_type].event_trigger;
 	phy_cfg_cmd.calib_control.flow_trigger =
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c linux-libre-4.16-gnu/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
--- linux-libre-4.16-rc7-gnu/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c	2018-04-01 17:20:27.000000000 -0400
@@ -2132,10 +2132,10 @@ static int iwl_mvm_start_ap_ibss(struct
 		 * Send the bcast station. At this stage the TBTT and DTIM time
 		 * events are added and applied to the scheduler
 		 */
-		iwl_mvm_send_add_bcast_sta(mvm, vif);
+		ret = iwl_mvm_send_add_bcast_sta(mvm, vif);
 		if (ret)
 			goto out_unbind;
-		iwl_mvm_add_mcast_sta(mvm, vif);
+		ret = iwl_mvm_add_mcast_sta(mvm, vif);
 		if (ret) {
 			iwl_mvm_send_rm_bcast_sta(mvm, vif);
 			goto out_unbind;
@@ -3494,6 +3494,7 @@ static int __iwl_mvm_assign_vif_chanctx(
 		ret = 0;
 		goto out;
 	case NL80211_IFTYPE_STATION:
+		mvmvif->csa_bcn_pending = false;
 		break;
 	case NL80211_IFTYPE_MONITOR:
 		/* always disable PS when a monitor interface is active */
@@ -3537,7 +3538,7 @@ static int __iwl_mvm_assign_vif_chanctx(
 	}
 
 	if (switching_chanctx && vif->type == NL80211_IFTYPE_STATION) {
-		u32 duration = 2 * vif->bss_conf.beacon_int;
+		u32 duration = 3 * vif->bss_conf.beacon_int;
 
 		/* iwl_mvm_protect_session() reads directly from the
 		 * device (the system time), so make sure it is
@@ -3550,6 +3551,7 @@ static int __iwl_mvm_assign_vif_chanctx(
 		/* Protect the session to make sure we hear the first
 		 * beacon on the new channel.
 		 */
+		mvmvif->csa_bcn_pending = true;
 		iwl_mvm_protect_session(mvm, vif, duration, duration,
 					vif->bss_conf.beacon_int / 2,
 					true);
@@ -3988,6 +3990,7 @@ static int iwl_mvm_post_channel_switch(s
 	if (vif->type == NL80211_IFTYPE_STATION) {
 		struct iwl_mvm_sta *mvmsta;
 
+		mvmvif->csa_bcn_pending = false;
 		mvmsta = iwl_mvm_sta_from_staid_protected(mvm,
 							  mvmvif->ap_sta_id);
 
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h linux-libre-4.16-gnu/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
--- linux-libre-4.16-rc7-gnu/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h	2018-04-01 17:20:27.000000000 -0400
@@ -438,6 +438,9 @@ struct iwl_mvm_vif {
 	bool csa_failed;
 	u16 csa_target_freq;
 
+	/* Indicates that we are waiting for a beacon on a new channel */
+	bool csa_bcn_pending;
+
 	/* TCP Checksum Offload */
 	netdev_features_t features;
 };
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c linux-libre-4.16-gnu/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c
--- linux-libre-4.16-rc7-gnu/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c	2018-04-01 17:20:27.000000000 -0400
@@ -8,6 +8,7 @@
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
  * Copyright(c) 2017           Intel Deutschland GmbH
+ * Copyright(c) 2018           Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -18,11 +19,6 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
- * USA
- *
  * The full GNU General Public License is included in this distribution
  * in the file called COPYING.
  *
@@ -34,6 +30,7 @@
  *
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
+ * Copyright(c) 2018           Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -286,6 +283,20 @@ void iwl_mvm_phy_ctxt_unref(struct iwl_m
 		return;
 
 	ctxt->ref--;
+
+	/*
+	 * Move unused phy's to a default channel. When the phy is moved the,
+	 * fw will cleanup immediate quiet bit if it was previously set,
+	 * otherwise we might not be able to reuse this phy.
+	 */
+	if (ctxt->ref == 0) {
+		struct ieee80211_channel *chan;
+		struct cfg80211_chan_def chandef;
+
+		chan = &mvm->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[0];
+		cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);
+		iwl_mvm_phy_ctxt_changed(mvm, ctxt, &chandef, 1, 1);
+	}
 }
 
 static void iwl_mvm_binding_iterator(void *_data, u8 *mac,
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/wireless/intel/iwlwifi/mvm/sta.c linux-libre-4.16-gnu/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
--- linux-libre-4.16-rc7-gnu/drivers/net/wireless/intel/iwlwifi/mvm/sta.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/wireless/intel/iwlwifi/mvm/sta.c	2018-04-01 17:20:27.000000000 -0400
@@ -1695,7 +1695,8 @@ int iwl_mvm_allocate_int_sta(struct iwl_
 			     u32 qmask, enum nl80211_iftype iftype,
 			     enum iwl_sta_type type)
 {
-	if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
+	if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) ||
+	    sta->sta_id == IWL_MVM_INVALID_STA) {
 		sta->sta_id = iwl_mvm_find_free_sta_id(mvm, iftype);
 		if (WARN_ON_ONCE(sta->sta_id == IWL_MVM_INVALID_STA))
 			return -ENOSPC;
@@ -2478,28 +2479,12 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_
 
 	/*
 	 * Note the possible cases:
-	 *  1. In DQA mode with an enabled TXQ - TXQ needs to become agg'ed
-	 *  2. Non-DQA mode: the TXQ hasn't yet been enabled, so find a free
-	 *	one and mark it as reserved
-	 *  3. In DQA mode, but no traffic yet on this TID: same treatment as in
-	 *	non-DQA mode, since the TXQ hasn't yet been allocated
-	 * Don't support case 3 for new TX path as it is not expected to happen
-	 * and aggregation will be offloaded soon anyway
+	 *  1. An enabled TXQ - TXQ needs to become agg'ed
+	 *  2. The TXQ hasn't yet been enabled, so find a free one and mark
+	 *	it as reserved
 	 */
 	txq_id = mvmsta->tid_data[tid].txq_id;
-	if (iwl_mvm_has_new_tx_api(mvm)) {
-		if (txq_id == IWL_MVM_INVALID_QUEUE) {
-			ret = -ENXIO;
-			goto release_locks;
-		}
-	} else if (unlikely(mvm->queue_info[txq_id].status ==
-			    IWL_MVM_QUEUE_SHARED)) {
-		ret = -ENXIO;
-		IWL_DEBUG_TX_QUEUES(mvm,
-				    "Can't start tid %d agg on shared queue!\n",
-				    tid);
-		goto release_locks;
-	} else if (mvm->queue_info[txq_id].status != IWL_MVM_QUEUE_READY) {
+	if (txq_id == IWL_MVM_INVALID_QUEUE) {
 		txq_id = iwl_mvm_find_free_queue(mvm, mvmsta->sta_id,
 						 IWL_MVM_DQA_MIN_DATA_QUEUE,
 						 IWL_MVM_DQA_MAX_DATA_QUEUE);
@@ -2508,16 +2493,16 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_
 			IWL_ERR(mvm, "Failed to allocate agg queue\n");
 			goto release_locks;
 		}
-		/*
-		 * TXQ shouldn't be in inactive mode for non-DQA, so getting
-		 * an inactive queue from iwl_mvm_find_free_queue() is
-		 * certainly a bug
-		 */
-		WARN_ON(mvm->queue_info[txq_id].status ==
-			IWL_MVM_QUEUE_INACTIVE);
 
 		/* TXQ hasn't yet been enabled, so mark it only as reserved */
 		mvm->queue_info[txq_id].status = IWL_MVM_QUEUE_RESERVED;
+	} else if (unlikely(mvm->queue_info[txq_id].status ==
+			    IWL_MVM_QUEUE_SHARED)) {
+		ret = -ENXIO;
+		IWL_DEBUG_TX_QUEUES(mvm,
+				    "Can't start tid %d agg on shared queue!\n",
+				    tid);
+		goto release_locks;
 	}
 
 	spin_unlock(&mvm->queue_info_lock);
@@ -2696,8 +2681,10 @@ out:
 
 static void iwl_mvm_unreserve_agg_queue(struct iwl_mvm *mvm,
 					struct iwl_mvm_sta *mvmsta,
-					u16 txq_id)
+					struct iwl_mvm_tid_data *tid_data)
 {
+	u16 txq_id = tid_data->txq_id;
+
 	if (iwl_mvm_has_new_tx_api(mvm))
 		return;
 
@@ -2709,8 +2696,10 @@ static void iwl_mvm_unreserve_agg_queue(
 	 * allocated through iwl_mvm_enable_txq, so we can just mark it back as
 	 * free.
 	 */
-	if (mvm->queue_info[txq_id].status == IWL_MVM_QUEUE_RESERVED)
+	if (mvm->queue_info[txq_id].status == IWL_MVM_QUEUE_RESERVED) {
 		mvm->queue_info[txq_id].status = IWL_MVM_QUEUE_FREE;
+		tid_data->txq_id = IWL_MVM_INVALID_QUEUE;
+	}
 
 	spin_unlock_bh(&mvm->queue_info_lock);
 }
@@ -2741,7 +2730,7 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_m
 
 	mvmsta->agg_tids &= ~BIT(tid);
 
-	iwl_mvm_unreserve_agg_queue(mvm, mvmsta, txq_id);
+	iwl_mvm_unreserve_agg_queue(mvm, mvmsta, tid_data);
 
 	switch (tid_data->state) {
 	case IWL_AGG_ON:
@@ -2808,7 +2797,7 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_
 	mvmsta->agg_tids &= ~BIT(tid);
 	spin_unlock_bh(&mvmsta->lock);
 
-	iwl_mvm_unreserve_agg_queue(mvm, mvmsta, txq_id);
+	iwl_mvm_unreserve_agg_queue(mvm, mvmsta, tid_data);
 
 	if (old_state >= IWL_AGG_ON) {
 		iwl_mvm_drain_sta(mvm, mvmsta, true);
@@ -3233,17 +3222,9 @@ int iwl_mvm_set_sta_key(struct iwl_mvm *
 		}
 		sta_id = mvm_sta->sta_id;
 
-		if (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
-		    keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||
-		    keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256) {
-			ret = iwl_mvm_send_sta_igtk(mvm, keyconf, sta_id,
-						    false);
-			goto end;
-		}
-
 		/*
 		 * It is possible that the 'sta' parameter is NULL, and thus
-		 * there is a need to retrieve  the sta from the local station
+		 * there is a need to retrieve the sta from the local station
 		 * table.
 		 */
 		if (!sta) {
@@ -3258,6 +3239,17 @@ int iwl_mvm_set_sta_key(struct iwl_mvm *
 
 		if (WARN_ON_ONCE(iwl_mvm_sta_from_mac80211(sta)->vif != vif))
 			return -EINVAL;
+	} else {
+		struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+
+		sta_id = mvmvif->mcast_sta.sta_id;
+	}
+
+	if (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
+	    keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||
+	    keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256) {
+		ret = iwl_mvm_send_sta_igtk(mvm, keyconf, sta_id, false);
+		goto end;
 	}
 
 	/* If the key_offset is not pre-assigned, we need to find a
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c linux-libre-4.16-gnu/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
--- linux-libre-4.16-rc7-gnu/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c	2018-04-01 17:20:27.000000000 -0400
@@ -8,6 +8,7 @@
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -18,11 +19,6 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
- * USA
- *
  * The full GNU General Public License is included in this distribution
  * in the file called COPYING.
  *
@@ -35,6 +31,7 @@
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -198,9 +195,13 @@ static bool iwl_mvm_te_check_disconnect(
 					struct ieee80211_vif *vif,
 					const char *errmsg)
 {
+	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+
 	if (vif->type != NL80211_IFTYPE_STATION)
 		return false;
-	if (vif->bss_conf.assoc && vif->bss_conf.dtim_period)
+
+	if (!mvmvif->csa_bcn_pending && vif->bss_conf.assoc &&
+	    vif->bss_conf.dtim_period)
 		return false;
 	if (errmsg)
 		IWL_ERR(mvm, "%s\n", errmsg);
@@ -344,7 +345,7 @@ static void iwl_mvm_te_handle_notif(stru
 			 * and know the dtim period.
 			 */
 			iwl_mvm_te_check_disconnect(mvm, te_data->vif,
-				"No association and the time event is over already...");
+				"No beacon heard and the time event is over already...");
 			break;
 		default:
 			break;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/wireless/intel/iwlwifi/mvm/tx.c linux-libre-4.16-gnu/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
--- linux-libre-4.16-rc7-gnu/drivers/net/wireless/intel/iwlwifi/mvm/tx.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/wireless/intel/iwlwifi/mvm/tx.c	2018-04-01 17:20:27.000000000 -0400
@@ -1894,14 +1894,12 @@ int iwl_mvm_flush_sta(struct iwl_mvm *mv
 	struct iwl_mvm_int_sta *int_sta = sta;
 	struct iwl_mvm_sta *mvm_sta = sta;
 
-	if (iwl_mvm_has_new_tx_api(mvm)) {
-		if (internal)
-			return iwl_mvm_flush_sta_tids(mvm, int_sta->sta_id,
-						      BIT(IWL_MGMT_TID), flags);
+	BUILD_BUG_ON(offsetof(struct iwl_mvm_int_sta, sta_id) !=
+		     offsetof(struct iwl_mvm_sta, sta_id));
 
+	if (iwl_mvm_has_new_tx_api(mvm))
 		return iwl_mvm_flush_sta_tids(mvm, mvm_sta->sta_id,
-					      0xFF, flags);
-	}
+					      0xff | BIT(IWL_MGMT_TID), flags);
 
 	if (internal)
 		return iwl_mvm_flush_tx_path(mvm, int_sta->tfd_queue_msk,
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/net/wireless/intel/iwlwifi/pcie/drv.c linux-libre-4.16-gnu/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
--- linux-libre-4.16-rc7-gnu/drivers/net/wireless/intel/iwlwifi/pcie/drv.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/net/wireless/intel/iwlwifi/pcie/drv.c	2018-04-01 17:20:27.000000000 -0400
@@ -579,25 +579,25 @@ static const struct pci_device_id iwl_hw
 	{IWL_PCI_DEVICE(0x30DC, 0x0264, iwl9461_2ac_cfg_soc)},
 	{IWL_PCI_DEVICE(0x30DC, 0x02A0, iwl9462_2ac_cfg_soc)},
 	{IWL_PCI_DEVICE(0x30DC, 0x02A4, iwl9462_2ac_cfg_soc)},
-	{IWL_PCI_DEVICE(0x31DC, 0x0030, iwl9560_2ac_cfg_soc)},
-	{IWL_PCI_DEVICE(0x31DC, 0x0034, iwl9560_2ac_cfg_soc)},
-	{IWL_PCI_DEVICE(0x31DC, 0x0038, iwl9560_2ac_cfg_soc)},
-	{IWL_PCI_DEVICE(0x31DC, 0x003C, iwl9560_2ac_cfg_soc)},
-	{IWL_PCI_DEVICE(0x31DC, 0x0060, iwl9460_2ac_cfg_soc)},
-	{IWL_PCI_DEVICE(0x31DC, 0x0064, iwl9461_2ac_cfg_soc)},
-	{IWL_PCI_DEVICE(0x31DC, 0x00A0, iwl9462_2ac_cfg_soc)},
-	{IWL_PCI_DEVICE(0x31DC, 0x00A4, iwl9462_2ac_cfg_soc)},
-	{IWL_PCI_DEVICE(0x31DC, 0x0230, iwl9560_2ac_cfg_soc)},
-	{IWL_PCI_DEVICE(0x31DC, 0x0234, iwl9560_2ac_cfg_soc)},
-	{IWL_PCI_DEVICE(0x31DC, 0x0238, iwl9560_2ac_cfg_soc)},
-	{IWL_PCI_DEVICE(0x31DC, 0x023C, iwl9560_2ac_cfg_soc)},
-	{IWL_PCI_DEVICE(0x31DC, 0x0260, iwl9461_2ac_cfg_soc)},
-	{IWL_PCI_DEVICE(0x31DC, 0x0264, iwl9461_2ac_cfg_soc)},
-	{IWL_PCI_DEVICE(0x31DC, 0x02A0, iwl9462_2ac_cfg_soc)},
-	{IWL_PCI_DEVICE(0x31DC, 0x02A4, iwl9462_2ac_cfg_soc)},
-	{IWL_PCI_DEVICE(0x31DC, 0x4030, iwl9560_2ac_cfg_soc)},
-	{IWL_PCI_DEVICE(0x31DC, 0x4034, iwl9560_2ac_cfg_soc)},
-	{IWL_PCI_DEVICE(0x31DC, 0x40A4, iwl9462_2ac_cfg_soc)},
+	{IWL_PCI_DEVICE(0x31DC, 0x0030, iwl9560_2ac_cfg_shared_clk)},
+	{IWL_PCI_DEVICE(0x31DC, 0x0034, iwl9560_2ac_cfg_shared_clk)},
+	{IWL_PCI_DEVICE(0x31DC, 0x0038, iwl9560_2ac_cfg_shared_clk)},
+	{IWL_PCI_DEVICE(0x31DC, 0x003C, iwl9560_2ac_cfg_shared_clk)},
+	{IWL_PCI_DEVICE(0x31DC, 0x0060, iwl9460_2ac_cfg_shared_clk)},
+	{IWL_PCI_DEVICE(0x31DC, 0x0064, iwl9461_2ac_cfg_shared_clk)},
+	{IWL_PCI_DEVICE(0x31DC, 0x00A0, iwl9462_2ac_cfg_shared_clk)},
+	{IWL_PCI_DEVICE(0x31DC, 0x00A4, iwl9462_2ac_cfg_shared_clk)},
+	{IWL_PCI_DEVICE(0x31DC, 0x0230, iwl9560_2ac_cfg_shared_clk)},
+	{IWL_PCI_DEVICE(0x31DC, 0x0234, iwl9560_2ac_cfg_shared_clk)},
+	{IWL_PCI_DEVICE(0x31DC, 0x0238, iwl9560_2ac_cfg_shared_clk)},
+	{IWL_PCI_DEVICE(0x31DC, 0x023C, iwl9560_2ac_cfg_shared_clk)},
+	{IWL_PCI_DEVICE(0x31DC, 0x0260, iwl9461_2ac_cfg_shared_clk)},
+	{IWL_PCI_DEVICE(0x31DC, 0x0264, iwl9461_2ac_cfg_shared_clk)},
+	{IWL_PCI_DEVICE(0x31DC, 0x02A0, iwl9462_2ac_cfg_shared_clk)},
+	{IWL_PCI_DEVICE(0x31DC, 0x02A4, iwl9462_2ac_cfg_shared_clk)},
+	{IWL_PCI_DEVICE(0x31DC, 0x4030, iwl9560_2ac_cfg_shared_clk)},
+	{IWL_PCI_DEVICE(0x31DC, 0x4034, iwl9560_2ac_cfg_shared_clk)},
+	{IWL_PCI_DEVICE(0x31DC, 0x40A4, iwl9462_2ac_cfg_shared_clk)},
 	{IWL_PCI_DEVICE(0x34F0, 0x0030, iwl9560_2ac_cfg_soc)},
 	{IWL_PCI_DEVICE(0x34F0, 0x0034, iwl9560_2ac_cfg_soc)},
 	{IWL_PCI_DEVICE(0x34F0, 0x02A4, iwl9462_2ac_cfg_soc)},
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/scsi/hosts.c linux-libre-4.16-gnu/drivers/scsi/hosts.c
--- linux-libre-4.16-rc7-gnu/drivers/scsi/hosts.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/scsi/hosts.c	2018-04-01 17:20:27.000000000 -0400
@@ -474,6 +474,7 @@ struct Scsi_Host *scsi_host_alloc(struct
 		shost->dma_boundary = 0xffffffff;
 
 	shost->use_blk_mq = scsi_use_blk_mq;
+	shost->use_blk_mq = scsi_use_blk_mq || shost->hostt->force_blk_mq;
 
 	device_initialize(&shost->shost_gendev);
 	dev_set_name(&shost->shost_gendev, "host%d", shost->host_no);
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/scsi/hpsa.c linux-libre-4.16-gnu/drivers/scsi/hpsa.c
--- linux-libre-4.16-rc7-gnu/drivers/scsi/hpsa.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/scsi/hpsa.c	2018-04-01 17:20:27.000000000 -0400
@@ -1045,11 +1045,7 @@ static void set_performant_mode(struct c
 		c->busaddr |= 1 | (h->blockFetchTable[c->Header.SGList] << 1);
 		if (unlikely(!h->msix_vectors))
 			return;
-		if (likely(reply_queue == DEFAULT_REPLY_QUEUE))
-			c->Header.ReplyQueue =
-				raw_smp_processor_id() % h->nreply_queues;
-		else
-			c->Header.ReplyQueue = reply_queue % h->nreply_queues;
+		c->Header.ReplyQueue = reply_queue;
 	}
 }
 
@@ -1063,10 +1059,7 @@ static void set_ioaccel1_performant_mode
 	 * Tell the controller to post the reply to the queue for this
 	 * processor.  This seems to give the best I/O throughput.
 	 */
-	if (likely(reply_queue == DEFAULT_REPLY_QUEUE))
-		cp->ReplyQueue = smp_processor_id() % h->nreply_queues;
-	else
-		cp->ReplyQueue = reply_queue % h->nreply_queues;
+	cp->ReplyQueue = reply_queue;
 	/*
 	 * Set the bits in the address sent down to include:
 	 *  - performant mode bit (bit 0)
@@ -1087,10 +1080,7 @@ static void set_ioaccel2_tmf_performant_
 	/* Tell the controller to post the reply to the queue for this
 	 * processor.  This seems to give the best I/O throughput.
 	 */
-	if (likely(reply_queue == DEFAULT_REPLY_QUEUE))
-		cp->reply_queue = smp_processor_id() % h->nreply_queues;
-	else
-		cp->reply_queue = reply_queue % h->nreply_queues;
+	cp->reply_queue = reply_queue;
 	/* Set the bits in the address sent down to include:
 	 *  - performant mode bit not used in ioaccel mode 2
 	 *  - pull count (bits 0-3)
@@ -1109,10 +1099,7 @@ static void set_ioaccel2_performant_mode
 	 * Tell the controller to post the reply to the queue for this
 	 * processor.  This seems to give the best I/O throughput.
 	 */
-	if (likely(reply_queue == DEFAULT_REPLY_QUEUE))
-		cp->reply_queue = smp_processor_id() % h->nreply_queues;
-	else
-		cp->reply_queue = reply_queue % h->nreply_queues;
+	cp->reply_queue = reply_queue;
 	/*
 	 * Set the bits in the address sent down to include:
 	 *  - performant mode bit not used in ioaccel mode 2
@@ -1157,6 +1144,8 @@ static void __enqueue_cmd_and_start_io(s
 {
 	dial_down_lockup_detection_during_fw_flash(h, c);
 	atomic_inc(&h->commands_outstanding);
+
+	reply_queue = h->reply_map[raw_smp_processor_id()];
 	switch (c->cmd_type) {
 	case CMD_IOACCEL1:
 		set_ioaccel1_performant_mode(h, c, reply_queue);
@@ -7376,6 +7365,26 @@ static void hpsa_disable_interrupt_mode(
 	h->msix_vectors = 0;
 }
 
+static void hpsa_setup_reply_map(struct ctlr_info *h)
+{
+	const struct cpumask *mask;
+	unsigned int queue, cpu;
+
+	for (queue = 0; queue < h->msix_vectors; queue++) {
+		mask = pci_irq_get_affinity(h->pdev, queue);
+		if (!mask)
+			goto fallback;
+
+		for_each_cpu(cpu, mask)
+			h->reply_map[cpu] = queue;
+	}
+	return;
+
+fallback:
+	for_each_possible_cpu(cpu)
+		h->reply_map[cpu] = 0;
+}
+
 /* If MSI/MSI-X is supported by the kernel we will try to enable it on
  * controllers that are capable. If not, we use legacy INTx mode.
  */
@@ -7771,6 +7780,10 @@ static int hpsa_pci_init(struct ctlr_inf
 	err = hpsa_interrupt_mode(h);
 	if (err)
 		goto clean1;
+
+	/* setup mapping between CPU and reply queue */
+	hpsa_setup_reply_map(h);
+
 	err = hpsa_pci_find_memory_BAR(h->pdev, &h->paddr);
 	if (err)
 		goto clean2;	/* intmode+region, pci */
@@ -8480,6 +8493,28 @@ static struct workqueue_struct *hpsa_cre
 	return wq;
 }
 
+static void hpda_free_ctlr_info(struct ctlr_info *h)
+{
+	kfree(h->reply_map);
+	kfree(h);
+}
+
+static struct ctlr_info *hpda_alloc_ctlr_info(void)
+{
+	struct ctlr_info *h;
+
+	h = kzalloc(sizeof(*h), GFP_KERNEL);
+	if (!h)
+		return NULL;
+
+	h->reply_map = kzalloc(sizeof(*h->reply_map) * nr_cpu_ids, GFP_KERNEL);
+	if (!h->reply_map) {
+		kfree(h);
+		return NULL;
+	}
+	return h;
+}
+
 static int hpsa_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
 	int dac, rc;
@@ -8517,7 +8552,7 @@ reinit_after_soft_reset:
 	 * the driver.  See comments in hpsa.h for more info.
 	 */
 	BUILD_BUG_ON(sizeof(struct CommandList) % COMMANDLIST_ALIGNMENT);
-	h = kzalloc(sizeof(*h), GFP_KERNEL);
+	h = hpda_alloc_ctlr_info();
 	if (!h) {
 		dev_err(&pdev->dev, "Failed to allocate controller head\n");
 		return -ENOMEM;
@@ -8916,7 +8951,7 @@ static void hpsa_remove_one(struct pci_d
 	h->lockup_detected = NULL;			/* init_one 2 */
 	/* (void) pci_disable_pcie_error_reporting(pdev); */	/* init_one 1 */
 
-	kfree(h);					/* init_one 1 */
+	hpda_free_ctlr_info(h);				/* init_one 1 */
 }
 
 static int hpsa_suspend(__attribute__((unused)) struct pci_dev *pdev,
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/scsi/hpsa.h linux-libre-4.16-gnu/drivers/scsi/hpsa.h
--- linux-libre-4.16-rc7-gnu/drivers/scsi/hpsa.h	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/scsi/hpsa.h	2018-04-01 17:20:27.000000000 -0400
@@ -158,6 +158,7 @@ struct bmic_controller_parameters {
 #pragma pack()
 
 struct ctlr_info {
+	unsigned int *reply_map;
 	int	ctlr;
 	char	devname[8];
 	char    *product_name;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/scsi/ibmvscsi/ibmvfc.c linux-libre-4.16-gnu/drivers/scsi/ibmvscsi/ibmvfc.c
--- linux-libre-4.16-rc7-gnu/drivers/scsi/ibmvscsi/ibmvfc.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/scsi/ibmvscsi/ibmvfc.c	2018-04-01 17:20:27.000000000 -0400
@@ -3579,11 +3579,9 @@ static void ibmvfc_tgt_implicit_logout(s
 static int ibmvfc_adisc_needs_plogi(struct ibmvfc_passthru_mad *mad,
 				    struct ibmvfc_target *tgt)
 {
-	if (memcmp(&mad->fc_iu.response[2], &tgt->ids.port_name,
-		   sizeof(tgt->ids.port_name)))
+	if (wwn_to_u64((u8 *)&mad->fc_iu.response[2]) != tgt->ids.port_name)
 		return 1;
-	if (memcmp(&mad->fc_iu.response[4], &tgt->ids.node_name,
-		   sizeof(tgt->ids.node_name)))
+	if (wwn_to_u64((u8 *)&mad->fc_iu.response[4]) != tgt->ids.node_name)
 		return 1;
 	if (be32_to_cpu(mad->fc_iu.response[6]) != tgt->scsi_id)
 		return 1;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/scsi/iscsi_tcp.c linux-libre-4.16-gnu/drivers/scsi/iscsi_tcp.c
--- linux-libre-4.16-rc7-gnu/drivers/scsi/iscsi_tcp.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/scsi/iscsi_tcp.c	2018-04-01 17:20:27.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/kfifo.h>
 #include <linux/scatterlist.h>
 #include <linux/module.h>
+#include <linux/backing-dev.h>
 #include <net/tcp.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
@@ -954,6 +955,13 @@ static int iscsi_sw_tcp_slave_alloc(stru
 
 static int iscsi_sw_tcp_slave_configure(struct scsi_device *sdev)
 {
+	struct iscsi_sw_tcp_host *tcp_sw_host = iscsi_host_priv(sdev->host);
+	struct iscsi_session *session = tcp_sw_host->session;
+	struct iscsi_conn *conn = session->leadconn;
+
+	if (conn->datadgst_en)
+		sdev->request_queue->backing_dev_info->capabilities
+			|= BDI_CAP_STABLE_WRITES;
 	blk_queue_bounce_limit(sdev->request_queue, BLK_BOUNCE_ANY);
 	blk_queue_dma_alignment(sdev->request_queue, 0);
 	return 0;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/scsi/megaraid/megaraid_sas_base.c linux-libre-4.16-gnu/drivers/scsi/megaraid/megaraid_sas_base.c
--- linux-libre-4.16-rc7-gnu/drivers/scsi/megaraid/megaraid_sas_base.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/scsi/megaraid/megaraid_sas_base.c	2018-04-01 17:20:27.000000000 -0400
@@ -5165,6 +5165,26 @@ skip_alloc:
 		instance->use_seqnum_jbod_fp = false;
 }
 
+static void megasas_setup_reply_map(struct megasas_instance *instance)
+{
+	const struct cpumask *mask;
+	unsigned int queue, cpu;
+
+	for (queue = 0; queue < instance->msix_vectors; queue++) {
+		mask = pci_irq_get_affinity(instance->pdev, queue);
+		if (!mask)
+			goto fallback;
+
+		for_each_cpu(cpu, mask)
+			instance->reply_map[cpu] = queue;
+	}
+	return;
+
+fallback:
+	for_each_possible_cpu(cpu)
+		instance->reply_map[cpu] = cpu % instance->msix_vectors;
+}
+
 /**
  * megasas_init_fw -	Initializes the FW
  * @instance:		Adapter soft state
@@ -5343,6 +5363,8 @@ static int megasas_init_fw(struct megasa
 			goto fail_setup_irqs;
 	}
 
+	megasas_setup_reply_map(instance);
+
 	dev_info(&instance->pdev->dev,
 		"firmware supports msix\t: (%d)", fw_msix_count);
 	dev_info(&instance->pdev->dev,
@@ -6123,20 +6145,29 @@ static inline int megasas_alloc_mfi_ctrl
  */
 static int megasas_alloc_ctrl_mem(struct megasas_instance *instance)
 {
+	instance->reply_map = kzalloc(sizeof(unsigned int) * nr_cpu_ids,
+				      GFP_KERNEL);
+	if (!instance->reply_map)
+		return -ENOMEM;
+
 	switch (instance->adapter_type) {
 	case MFI_SERIES:
 		if (megasas_alloc_mfi_ctrl_mem(instance))
-			return -ENOMEM;
+			goto fail;
 		break;
 	case VENTURA_SERIES:
 	case THUNDERBOLT_SERIES:
 	case INVADER_SERIES:
 		if (megasas_alloc_fusion_context(instance))
-			return -ENOMEM;
+			goto fail;
 		break;
 	}
 
 	return 0;
+ fail:
+	kfree(instance->reply_map);
+	instance->reply_map = NULL;
+	return -ENOMEM;
 }
 
 /*
@@ -6148,6 +6179,7 @@ static int megasas_alloc_ctrl_mem(struct
  */
 static inline void megasas_free_ctrl_mem(struct megasas_instance *instance)
 {
+	kfree(instance->reply_map);
 	if (instance->adapter_type == MFI_SERIES) {
 		if (instance->producer)
 			pci_free_consistent(instance->pdev, sizeof(u32),
@@ -6540,7 +6572,6 @@ fail_io_attach:
 		pci_free_irq_vectors(instance->pdev);
 fail_init_mfi:
 	scsi_host_put(host);
-
 fail_alloc_instance:
 	pci_disable_device(pdev);
 
@@ -6746,6 +6777,8 @@ megasas_resume(struct pci_dev *pdev)
 	if (rval < 0)
 		goto fail_reenable_msix;
 
+	megasas_setup_reply_map(instance);
+
 	if (instance->adapter_type != MFI_SERIES) {
 		megasas_reset_reply_desc(instance);
 		if (megasas_ioc_init_fusion(instance)) {
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/scsi/megaraid/megaraid_sas_fusion.c linux-libre-4.16-gnu/drivers/scsi/megaraid/megaraid_sas_fusion.c
--- linux-libre-4.16-rc7-gnu/drivers/scsi/megaraid/megaraid_sas_fusion.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/scsi/megaraid/megaraid_sas_fusion.c	2018-04-01 17:20:27.000000000 -0400
@@ -2641,11 +2641,8 @@ megasas_build_ldio_fusion(struct megasas
 			fp_possible = (io_info.fpOkForIo > 0) ? true : false;
 	}
 
-	/* Use raw_smp_processor_id() for now until cmd->request->cpu is CPU
-	   id by default, not CPU group id, otherwise all MSI-X queues won't
-	   be utilized */
-	cmd->request_desc->SCSIIO.MSIxIndex = instance->msix_vectors ?
-		raw_smp_processor_id() % instance->msix_vectors : 0;
+	cmd->request_desc->SCSIIO.MSIxIndex =
+		instance->reply_map[raw_smp_processor_id()];
 
 	praid_context = &io_request->RaidContext;
 
@@ -2971,10 +2968,9 @@ megasas_build_syspd_fusion(struct megasa
 	}
 
 	cmd->request_desc->SCSIIO.DevHandle = io_request->DevHandle;
-	cmd->request_desc->SCSIIO.MSIxIndex =
-		instance->msix_vectors ?
-		(raw_smp_processor_id() % instance->msix_vectors) : 0;
 
+	cmd->request_desc->SCSIIO.MSIxIndex =
+		instance->reply_map[raw_smp_processor_id()];
 
 	if (!fp_possible) {
 		/* system pd firmware path */
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/scsi/megaraid/megaraid_sas.h linux-libre-4.16-gnu/drivers/scsi/megaraid/megaraid_sas.h
--- linux-libre-4.16-rc7-gnu/drivers/scsi/megaraid/megaraid_sas.h	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/scsi/megaraid/megaraid_sas.h	2018-04-01 17:20:27.000000000 -0400
@@ -2128,6 +2128,7 @@ enum MR_PD_TYPE {
 
 struct megasas_instance {
 
+	unsigned int *reply_map;
 	__le32 *producer;
 	dma_addr_t producer_h;
 	__le32 *consumer;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/scsi/sd.c linux-libre-4.16-gnu/drivers/scsi/sd.c
--- linux-libre-4.16-rc7-gnu/drivers/scsi/sd.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/scsi/sd.c	2018-04-01 17:20:27.000000000 -0400
@@ -2484,6 +2484,8 @@ sd_read_capacity(struct scsi_disk *sdkp,
 				sector_size = old_sector_size;
 				goto got_data;
 			}
+			/* Remember that READ CAPACITY(16) succeeded */
+			sdp->try_rc_10_first = 0;
 		}
 	}
 
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/scsi/virtio_scsi.c linux-libre-4.16-gnu/drivers/scsi/virtio_scsi.c
--- linux-libre-4.16-rc7-gnu/drivers/scsi/virtio_scsi.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/scsi/virtio_scsi.c	2018-04-01 17:20:27.000000000 -0400
@@ -91,9 +91,6 @@ struct virtio_scsi_vq {
 struct virtio_scsi_target_state {
 	seqcount_t tgt_seq;
 
-	/* Count of outstanding requests. */
-	atomic_t reqs;
-
 	/* Currently active virtqueue for requests sent to this target. */
 	struct virtio_scsi_vq *req_vq;
 };
@@ -152,8 +149,6 @@ static void virtscsi_complete_cmd(struct
 	struct virtio_scsi_cmd *cmd = buf;
 	struct scsi_cmnd *sc = cmd->sc;
 	struct virtio_scsi_cmd_resp *resp = &cmd->resp.cmd;
-	struct virtio_scsi_target_state *tgt =
-				scsi_target(sc->device)->hostdata;
 
 	dev_dbg(&sc->device->sdev_gendev,
 		"cmd %p response %u status %#02x sense_len %u\n",
@@ -210,8 +205,6 @@ static void virtscsi_complete_cmd(struct
 	}
 
 	sc->scsi_done(sc);
-
-	atomic_dec(&tgt->reqs);
 }
 
 static void virtscsi_vq_done(struct virtio_scsi *vscsi,
@@ -529,11 +522,20 @@ static void virtio_scsi_init_hdr_pi(stru
 }
 #endif
 
-static int virtscsi_queuecommand(struct virtio_scsi *vscsi,
-				 struct virtio_scsi_vq *req_vq,
+static struct virtio_scsi_vq *virtscsi_pick_vq_mq(struct virtio_scsi *vscsi,
+						  struct scsi_cmnd *sc)
+{
+	u32 tag = blk_mq_unique_tag(sc->request);
+	u16 hwq = blk_mq_unique_tag_to_hwq(tag);
+
+	return &vscsi->req_vqs[hwq];
+}
+
+static int virtscsi_queuecommand(struct Scsi_Host *shost,
 				 struct scsi_cmnd *sc)
 {
-	struct Scsi_Host *shost = virtio_scsi_host(vscsi->vdev);
+	struct virtio_scsi *vscsi = shost_priv(shost);
+	struct virtio_scsi_vq *req_vq = virtscsi_pick_vq_mq(vscsi, sc);
 	struct virtio_scsi_cmd *cmd = scsi_cmd_priv(sc);
 	unsigned long flags;
 	int req_size;
@@ -576,79 +578,6 @@ static int virtscsi_queuecommand(struct
 	return 0;
 }
 
-static int virtscsi_queuecommand_single(struct Scsi_Host *sh,
-					struct scsi_cmnd *sc)
-{
-	struct virtio_scsi *vscsi = shost_priv(sh);
-	struct virtio_scsi_target_state *tgt =
-				scsi_target(sc->device)->hostdata;
-
-	atomic_inc(&tgt->reqs);
-	return virtscsi_queuecommand(vscsi, &vscsi->req_vqs[0], sc);
-}
-
-static struct virtio_scsi_vq *virtscsi_pick_vq_mq(struct virtio_scsi *vscsi,
-						  struct scsi_cmnd *sc)
-{
-	u32 tag = blk_mq_unique_tag(sc->request);
-	u16 hwq = blk_mq_unique_tag_to_hwq(tag);
-
-	return &vscsi->req_vqs[hwq];
-}
-
-static struct virtio_scsi_vq *virtscsi_pick_vq(struct virtio_scsi *vscsi,
-					       struct virtio_scsi_target_state *tgt)
-{
-	struct virtio_scsi_vq *vq;
-	unsigned long flags;
-	u32 queue_num;
-
-	local_irq_save(flags);
-	if (atomic_inc_return(&tgt->reqs) > 1) {
-		unsigned long seq;
-
-		do {
-			seq = read_seqcount_begin(&tgt->tgt_seq);
-			vq = tgt->req_vq;
-		} while (read_seqcount_retry(&tgt->tgt_seq, seq));
-	} else {
-		/* no writes can be concurrent because of atomic_t */
-		write_seqcount_begin(&tgt->tgt_seq);
-
-		/* keep previous req_vq if a reader just arrived */
-		if (unlikely(atomic_read(&tgt->reqs) > 1)) {
-			vq = tgt->req_vq;
-			goto unlock;
-		}
-
-		queue_num = smp_processor_id();
-		while (unlikely(queue_num >= vscsi->num_queues))
-			queue_num -= vscsi->num_queues;
-		tgt->req_vq = vq = &vscsi->req_vqs[queue_num];
- unlock:
-		write_seqcount_end(&tgt->tgt_seq);
-	}
-	local_irq_restore(flags);
-
-	return vq;
-}
-
-static int virtscsi_queuecommand_multi(struct Scsi_Host *sh,
-				       struct scsi_cmnd *sc)
-{
-	struct virtio_scsi *vscsi = shost_priv(sh);
-	struct virtio_scsi_target_state *tgt =
-				scsi_target(sc->device)->hostdata;
-	struct virtio_scsi_vq *req_vq;
-
-	if (shost_use_blk_mq(sh))
-		req_vq = virtscsi_pick_vq_mq(vscsi, sc);
-	else
-		req_vq = virtscsi_pick_vq(vscsi, tgt);
-
-	return virtscsi_queuecommand(vscsi, req_vq, sc);
-}
-
 static int virtscsi_tmf(struct virtio_scsi *vscsi, struct virtio_scsi_cmd *cmd)
 {
 	DECLARE_COMPLETION_ONSTACK(comp);
@@ -775,7 +704,6 @@ static int virtscsi_target_alloc(struct
 		return -ENOMEM;
 
 	seqcount_init(&tgt->tgt_seq);
-	atomic_set(&tgt->reqs, 0);
 	tgt->req_vq = &vscsi->req_vqs[0];
 
 	starget->hostdata = tgt;
@@ -805,33 +733,13 @@ static enum blk_eh_timer_return virtscsi
 	return BLK_EH_RESET_TIMER;
 }
 
-static struct scsi_host_template virtscsi_host_template_single = {
-	.module = THIS_MODULE,
-	.name = "Virtio SCSI HBA",
-	.proc_name = "virtio_scsi",
-	.this_id = -1,
-	.cmd_size = sizeof(struct virtio_scsi_cmd),
-	.queuecommand = virtscsi_queuecommand_single,
-	.change_queue_depth = virtscsi_change_queue_depth,
-	.eh_abort_handler = virtscsi_abort,
-	.eh_device_reset_handler = virtscsi_device_reset,
-	.eh_timed_out = virtscsi_eh_timed_out,
-	.slave_alloc = virtscsi_device_alloc,
-
-	.dma_boundary = UINT_MAX,
-	.use_clustering = ENABLE_CLUSTERING,
-	.target_alloc = virtscsi_target_alloc,
-	.target_destroy = virtscsi_target_destroy,
-	.track_queue_depth = 1,
-};
-
-static struct scsi_host_template virtscsi_host_template_multi = {
+static struct scsi_host_template virtscsi_host_template = {
 	.module = THIS_MODULE,
 	.name = "Virtio SCSI HBA",
 	.proc_name = "virtio_scsi",
 	.this_id = -1,
 	.cmd_size = sizeof(struct virtio_scsi_cmd),
-	.queuecommand = virtscsi_queuecommand_multi,
+	.queuecommand = virtscsi_queuecommand,
 	.change_queue_depth = virtscsi_change_queue_depth,
 	.eh_abort_handler = virtscsi_abort,
 	.eh_device_reset_handler = virtscsi_device_reset,
@@ -844,6 +752,7 @@ static struct scsi_host_template virtscs
 	.target_destroy = virtscsi_target_destroy,
 	.map_queues = virtscsi_map_queues,
 	.track_queue_depth = 1,
+	.force_blk_mq = 1,
 };
 
 #define virtscsi_config_get(vdev, fld) \
@@ -936,7 +845,6 @@ static int virtscsi_probe(struct virtio_
 	u32 sg_elems, num_targets;
 	u32 cmd_per_lun;
 	u32 num_queues;
-	struct scsi_host_template *hostt;
 
 	if (!vdev->config->get) {
 		dev_err(&vdev->dev, "%s failure: config access disabled\n",
@@ -949,12 +857,7 @@ static int virtscsi_probe(struct virtio_
 
 	num_targets = virtscsi_config_get(vdev, max_target) + 1;
 
-	if (num_queues == 1)
-		hostt = &virtscsi_host_template_single;
-	else
-		hostt = &virtscsi_host_template_multi;
-
-	shost = scsi_host_alloc(hostt,
+	shost = scsi_host_alloc(&virtscsi_host_template,
 		sizeof(*vscsi) + sizeof(vscsi->req_vqs[0]) * num_queues);
 	if (!shost)
 		return -ENOMEM;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/vhost/net.c linux-libre-4.16-gnu/drivers/vhost/net.c
--- linux-libre-4.16-rc7-gnu/drivers/vhost/net.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/vhost/net.c	2018-04-01 17:20:27.000000000 -0400
@@ -630,7 +630,7 @@ static int vhost_net_rx_peek_head_len(st
 
 	if (!len && vq->busyloop_timeout) {
 		/* Both tx vq and rx socket were polled here */
-		mutex_lock(&vq->mutex);
+		mutex_lock_nested(&vq->mutex, 1);
 		vhost_disable_notify(&net->dev, vq);
 
 		preempt_disable();
@@ -763,7 +763,7 @@ static void handle_rx(struct vhost_net *
 	struct iov_iter fixup;
 	__virtio16 num_buffers;
 
-	mutex_lock(&vq->mutex);
+	mutex_lock_nested(&vq->mutex, 0);
 	sock = vq->private_data;
 	if (!sock)
 		goto out;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/drivers/vhost/vhost.c linux-libre-4.16-gnu/drivers/vhost/vhost.c
--- linux-libre-4.16-rc7-gnu/drivers/vhost/vhost.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/drivers/vhost/vhost.c	2018-04-01 17:20:27.000000000 -0400
@@ -212,8 +212,7 @@ int vhost_poll_start(struct vhost_poll *
 	if (mask)
 		vhost_poll_wakeup(&poll->wait, 0, 0, poll_to_key(mask));
 	if (mask & EPOLLERR) {
-		if (poll->wqh)
-			remove_wait_queue(poll->wqh, &poll->wait);
+		vhost_poll_stop(poll);
 		ret = -EINVAL;
 	}
 
@@ -1245,14 +1244,12 @@ static int vq_log_access_ok(struct vhost
 /* Caller should have vq mutex and device mutex */
 int vhost_vq_access_ok(struct vhost_virtqueue *vq)
 {
-	if (vq->iotlb) {
-		/* When device IOTLB was used, the access validation
-		 * will be validated during prefetching.
-		 */
-		return 1;
-	}
-	return vq_access_ok(vq, vq->num, vq->desc, vq->avail, vq->used) &&
-		vq_log_access_ok(vq, vq->log_base);
+	int ret = vq_log_access_ok(vq, vq->log_base);
+
+	if (ret || vq->iotlb)
+		return ret;
+
+	return vq_access_ok(vq, vq->num, vq->desc, vq->avail, vq->used);
 }
 EXPORT_SYMBOL_GPL(vhost_vq_access_ok);
 
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/fs/ceph/file.c linux-libre-4.16-gnu/fs/ceph/file.c
--- linux-libre-4.16-rc7-gnu/fs/ceph/file.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/fs/ceph/file.c	2018-04-01 17:20:27.000000000 -0400
@@ -640,7 +640,8 @@ static ssize_t ceph_sync_read(struct kio
 struct ceph_aio_request {
 	struct kiocb *iocb;
 	size_t total_len;
-	int write;
+	bool write;
+	bool should_dirty;
 	int error;
 	struct list_head osd_reqs;
 	unsigned num_reqs;
@@ -750,7 +751,7 @@ static void ceph_aio_complete_req(struct
 		}
 	}
 
-	ceph_put_page_vector(osd_data->pages, num_pages, !aio_req->write);
+	ceph_put_page_vector(osd_data->pages, num_pages, aio_req->should_dirty);
 	ceph_osdc_put_request(req);
 
 	if (rc < 0)
@@ -847,6 +848,7 @@ ceph_direct_read_write(struct kiocb *ioc
 	size_t count = iov_iter_count(iter);
 	loff_t pos = iocb->ki_pos;
 	bool write = iov_iter_rw(iter) == WRITE;
+	bool should_dirty = !write && iter_is_iovec(iter);
 
 	if (write && ceph_snap(file_inode(file)) != CEPH_NOSNAP)
 		return -EROFS;
@@ -914,6 +916,7 @@ ceph_direct_read_write(struct kiocb *ioc
 			if (aio_req) {
 				aio_req->iocb = iocb;
 				aio_req->write = write;
+				aio_req->should_dirty = should_dirty;
 				INIT_LIST_HEAD(&aio_req->osd_reqs);
 				if (write) {
 					aio_req->mtime = mtime;
@@ -971,7 +974,7 @@ ceph_direct_read_write(struct kiocb *ioc
 				len = ret;
 		}
 
-		ceph_put_page_vector(pages, num_pages, !write);
+		ceph_put_page_vector(pages, num_pages, should_dirty);
 
 		ceph_osdc_put_request(req);
 		if (ret < 0)
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/include/linux/if_vlan.h linux-libre-4.16-gnu/include/linux/if_vlan.h
--- linux-libre-4.16-rc7-gnu/include/linux/if_vlan.h	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/include/linux/if_vlan.h	2018-04-01 17:20:27.000000000 -0400
@@ -323,13 +323,24 @@ static inline int __vlan_insert_inner_ta
 	skb_push(skb, VLAN_HLEN);
 
 	/* Move the mac header sans proto to the beginning of the new header. */
-	memmove(skb->data, skb->data + VLAN_HLEN, mac_len - ETH_TLEN);
+	if (likely(mac_len > ETH_TLEN))
+		memmove(skb->data, skb->data + VLAN_HLEN, mac_len - ETH_TLEN);
 	skb->mac_header -= VLAN_HLEN;
 
 	veth = (struct vlan_ethhdr *)(skb->data + mac_len - ETH_HLEN);
 
 	/* first, the ethernet type */
-	veth->h_vlan_proto = vlan_proto;
+	if (likely(mac_len >= ETH_TLEN)) {
+		/* h_vlan_encapsulated_proto should already be populated, and
+		 * skb->data has space for h_vlan_proto
+		 */
+		veth->h_vlan_proto = vlan_proto;
+	} else {
+		/* h_vlan_encapsulated_proto should not be populated, and
+		 * skb->data has no space for h_vlan_proto
+		 */
+		veth->h_vlan_encapsulated_proto = skb->protocol;
+	}
 
 	/* now, the TCI */
 	veth->h_vlan_TCI = htons(vlan_tci);
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/include/linux/net_dim.h linux-libre-4.16-gnu/include/linux/net_dim.h
--- linux-libre-4.16-rc7-gnu/include/linux/net_dim.h	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/include/linux/net_dim.h	2018-04-01 17:20:27.000000000 -0400
@@ -231,7 +231,7 @@ static inline void net_dim_exit_parking(
 }
 
 #define IS_SIGNIFICANT_DIFF(val, ref) \
-	(((100 * abs((val) - (ref))) / (ref)) > 10) /* more than 10% difference */
+	(((100UL * abs((val) - (ref))) / (ref)) > 10) /* more than 10% difference */
 
 static inline int net_dim_stats_compare(struct net_dim_stats *curr,
 					struct net_dim_stats *prev)
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/include/net/llc_conn.h linux-libre-4.16-gnu/include/net/llc_conn.h
--- linux-libre-4.16-rc7-gnu/include/net/llc_conn.h	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/include/net/llc_conn.h	2018-04-01 17:20:27.000000000 -0400
@@ -103,7 +103,7 @@ void llc_sk_reset(struct sock *sk);
 
 /* Access to a connection */
 int llc_conn_state_process(struct sock *sk, struct sk_buff *skb);
-void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb);
+int llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb);
 void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb);
 void llc_conn_resend_i_pdu_as_cmd(struct sock *sk, u8 nr, u8 first_p_bit);
 void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr, u8 first_f_bit);
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/include/net/netfilter/nf_tables.h linux-libre-4.16-gnu/include/net/netfilter/nf_tables.h
--- linux-libre-4.16-rc7-gnu/include/net/netfilter/nf_tables.h	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/include/net/netfilter/nf_tables.h	2018-04-01 17:20:27.000000000 -0400
@@ -1068,6 +1068,8 @@ struct nft_object_ops {
 int nft_register_obj(struct nft_object_type *obj_type);
 void nft_unregister_obj(struct nft_object_type *obj_type);
 
+#define NFT_FLOWTABLE_DEVICE_MAX	8
+
 /**
  *	struct nft_flowtable - nf_tables flow table
  *
@@ -1080,6 +1082,7 @@ void nft_unregister_obj(struct nft_objec
  *	@genmask: generation mask
  *	@use: number of references to this flow table
  * 	@handle: unique object handle
+ *	@dev_name: array of device names
  *	@data: rhashtable and garbage collector
  * 	@ops: array of hooks
  */
@@ -1093,6 +1096,7 @@ struct nft_flowtable {
 	u32				genmask:2,
 					use:30;
 	u64				handle;
+	char				*dev_name[NFT_FLOWTABLE_DEVICE_MAX];
 	/* runtime data below here */
 	struct nf_hook_ops		*ops ____cacheline_aligned;
 	struct nf_flowtable		data;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/include/net/sch_generic.h linux-libre-4.16-gnu/include/net/sch_generic.h
--- linux-libre-4.16-rc7-gnu/include/net/sch_generic.h	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/include/net/sch_generic.h	2018-04-01 17:20:27.000000000 -0400
@@ -30,6 +30,7 @@ struct qdisc_rate_table {
 enum qdisc_state_t {
 	__QDISC_STATE_SCHED,
 	__QDISC_STATE_DEACTIVATED,
+	__QDISC_STATE_RUNNING,
 };
 
 struct qdisc_size_table {
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/include/rdma/ib_addr.h linux-libre-4.16-gnu/include/rdma/ib_addr.h
--- linux-libre-4.16-rc7-gnu/include/rdma/ib_addr.h	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/include/rdma/ib_addr.h	2018-04-01 17:20:27.000000000 -0400
@@ -130,6 +130,8 @@ void rdma_copy_addr(struct rdma_dev_addr
 		    const unsigned char *dst_dev_addr);
 
 int rdma_addr_size(struct sockaddr *addr);
+int rdma_addr_size_in6(struct sockaddr_in6 *addr);
+int rdma_addr_size_kss(struct __kernel_sockaddr_storage *addr);
 
 int rdma_addr_find_l2_eth_by_grh(const union ib_gid *sgid,
 				 const union ib_gid *dgid,
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/include/scsi/scsi_host.h linux-libre-4.16-gnu/include/scsi/scsi_host.h
--- linux-libre-4.16-rc7-gnu/include/scsi/scsi_host.h	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/include/scsi/scsi_host.h	2018-04-01 17:20:27.000000000 -0400
@@ -452,6 +452,9 @@ struct scsi_host_template {
 	/* True if the controller does not support WRITE SAME */
 	unsigned no_write_same:1;
 
+	/* True if the low-level driver supports blk-mq only */
+	unsigned force_blk_mq:1;
+
 	/*
 	 * Countdown for host blocking with no commands outstanding.
 	 */
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/ipc/shm.c linux-libre-4.16-gnu/ipc/shm.c
--- linux-libre-4.16-rc7-gnu/ipc/shm.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/ipc/shm.c	2018-04-01 17:20:27.000000000 -0400
@@ -386,6 +386,17 @@ static int shm_fault(struct vm_fault *vm
 	return sfd->vm_ops->fault(vmf);
 }
 
+static int shm_split(struct vm_area_struct *vma, unsigned long addr)
+{
+	struct file *file = vma->vm_file;
+	struct shm_file_data *sfd = shm_file_data(file);
+
+	if (sfd->vm_ops && sfd->vm_ops->split)
+		return sfd->vm_ops->split(vma, addr);
+
+	return 0;
+}
+
 #ifdef CONFIG_NUMA
 static int shm_set_policy(struct vm_area_struct *vma, struct mempolicy *new)
 {
@@ -510,6 +521,7 @@ static const struct vm_operations_struct
 	.open	= shm_open,	/* callback for a new vm-area open */
 	.close	= shm_close,	/* callback for when the vm-area is released */
 	.fault	= shm_fault,
+	.split	= shm_split,
 #if defined(CONFIG_NUMA)
 	.set_policy = shm_set_policy,
 	.get_policy = shm_get_policy,
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/kernel/events/hw_breakpoint.c linux-libre-4.16-gnu/kernel/events/hw_breakpoint.c
--- linux-libre-4.16-rc7-gnu/kernel/events/hw_breakpoint.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/kernel/events/hw_breakpoint.c	2018-04-01 17:20:27.000000000 -0400
@@ -427,16 +427,9 @@ EXPORT_SYMBOL_GPL(register_user_hw_break
  * modify_user_hw_breakpoint - modify a user-space hardware breakpoint
  * @bp: the breakpoint structure to modify
  * @attr: new breakpoint attributes
- * @triggered: callback to trigger when we hit the breakpoint
- * @tsk: pointer to 'task_struct' of the process to which the address belongs
  */
 int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *attr)
 {
-	u64 old_addr = bp->attr.bp_addr;
-	u64 old_len = bp->attr.bp_len;
-	int old_type = bp->attr.bp_type;
-	int err = 0;
-
 	/*
 	 * modify_user_hw_breakpoint can be invoked with IRQs disabled and hence it
 	 * will not be possible to raise IPIs that invoke __perf_event_disable.
@@ -451,27 +444,18 @@ int modify_user_hw_breakpoint(struct per
 	bp->attr.bp_addr = attr->bp_addr;
 	bp->attr.bp_type = attr->bp_type;
 	bp->attr.bp_len = attr->bp_len;
+	bp->attr.disabled = 1;
 
-	if (attr->disabled)
-		goto end;
-
-	err = validate_hw_breakpoint(bp);
-	if (!err)
-		perf_event_enable(bp);
+	if (!attr->disabled) {
+		int err = validate_hw_breakpoint(bp);
 
-	if (err) {
-		bp->attr.bp_addr = old_addr;
-		bp->attr.bp_type = old_type;
-		bp->attr.bp_len = old_len;
-		if (!bp->attr.disabled)
-			perf_event_enable(bp);
+		if (err)
+			return err;
 
-		return err;
+		perf_event_enable(bp);
+		bp->attr.disabled = 0;
 	}
 
-end:
-	bp->attr.disabled = attr->disabled;
-
 	return 0;
 }
 EXPORT_SYMBOL_GPL(modify_user_hw_breakpoint);
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/.mailmap linux-libre-4.16-gnu/.mailmap
--- linux-libre-4.16-rc7-gnu/.mailmap	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/.mailmap	2018-04-01 17:20:27.000000000 -0400
@@ -62,6 +62,7 @@ Frank Zago <fzago@systemfabricworks.com>
 Greg Kroah-Hartman <greg@echidna.(none)>
 Greg Kroah-Hartman <gregkh@suse.de>
 Greg Kroah-Hartman <greg@kroah.com>
+Gregory CLEMENT <gregory.clement@bootlin.com> <gregory.clement@free-electrons.com>
 Henk Vergonet <Henk.Vergonet@gmail.com>
 Henrik Kretzschmar <henne@nachtwindheim.de>
 Henrik Rydberg <rydberg@bitmath.org>
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/MAINTAINERS linux-libre-4.16-gnu/MAINTAINERS
--- linux-libre-4.16-rc7-gnu/MAINTAINERS	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/MAINTAINERS	2018-04-01 17:20:27.000000000 -0400
@@ -1060,41 +1060,42 @@ ARM PORT
 M:	Russell King <linux@armlinux.org.uk>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 W:	http://www.armlinux.org.uk/
-S:	Maintained
+S:	Odd Fixes
 T:	git git://git.armlinux.org.uk/~rmk/linux-arm.git
 F:	arch/arm/
+X:	arch/arm/boot/dts/
 
 ARM PRIMECELL AACI PL041 DRIVER
 M:	Russell King <linux@armlinux.org.uk>
-S:	Maintained
+S:	Odd Fixes
 F:	sound/arm/aaci.*
 
 ARM PRIMECELL BUS SUPPORT
 M:	Russell King <linux@armlinux.org.uk>
-S:	Maintained
+S:	Odd Fixes
 F:	drivers/amba/
 F:	include/linux/amba/bus.h
 
 ARM PRIMECELL CLCD PL110 DRIVER
 M:	Russell King <linux@armlinux.org.uk>
-S:	Maintained
+S:	Odd Fixes
 F:	drivers/video/fbdev/amba-clcd.*
 
 ARM PRIMECELL KMI PL050 DRIVER
 M:	Russell King <linux@armlinux.org.uk>
-S:	Maintained
+S:	Odd Fixes
 F:	drivers/input/serio/ambakmi.*
 F:	include/linux/amba/kmi.h
 
 ARM PRIMECELL MMCI PL180/1 DRIVER
 M:	Russell King <linux@armlinux.org.uk>
-S:	Maintained
+S:	Odd Fixes
 F:	drivers/mmc/host/mmci.*
 F:	include/linux/amba/mmci.h
 
 ARM PRIMECELL UART PL010 AND PL011 DRIVERS
 M:	Russell King <linux@armlinux.org.uk>
-S:	Maintained
+S:	Odd Fixes
 F:	drivers/tty/serial/amba-pl01*.c
 F:	include/linux/amba/serial.h
 
@@ -1152,7 +1153,7 @@ S:	Maintained
 F:	drivers/clk/sunxi/
 
 ARM/Allwinner sunXi SoC support
-M:	Maxime Ripard <maxime.ripard@free-electrons.com>
+M:	Maxime Ripard <maxime.ripard@bootlin.com>
 M:	Chen-Yu Tsai <wens@csie.org>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
@@ -4626,7 +4627,7 @@ F:	include/uapi/drm/drm*
 F:	include/linux/vga*
 
 DRM DRIVERS FOR ALLWINNER A10
-M:	Maxime Ripard  <maxime.ripard@free-electrons.com>
+M:	Maxime Ripard  <maxime.ripard@bootlin.com>
 L:	dri-devel@lists.freedesktop.org
 S:	Supported
 F:	drivers/gpu/drm/sun4i/
@@ -8434,7 +8435,7 @@ S:	Orphan
 F:	drivers/net/wireless/marvell/libertas/
 
 MARVELL MACCHIATOBIN SUPPORT
-M:	Russell King <rmk@armlinux.org.uk>
+M:	Russell King <linux@armlinux.org.uk>
 L:	linux-arm-kernel@lists.infradead.org
 S:	Maintained
 F:	arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts
@@ -8447,7 +8448,7 @@ F:	drivers/net/ethernet/marvell/mv643xx_
 F:	include/linux/mv643xx.h
 
 MARVELL MV88X3310 PHY DRIVER
-M:	Russell King <rmk@armlinux.org.uk>
+M:	Russell King <linux@armlinux.org.uk>
 L:	netdev@vger.kernel.org
 S:	Maintained
 F:	drivers/net/phy/marvell10g.c
@@ -12875,6 +12876,19 @@ S:	Maintained
 F:	drivers/net/ethernet/socionext/netsec.c
 F:	Documentation/devicetree/bindings/net/socionext-netsec.txt
 
+SOLIDRUN CLEARFOG SUPPORT
+M:	Russell King <linux@armlinux.org.uk>
+S:	Maintained
+F:	arch/arm/boot/dts/armada-388-clearfog*
+F:	arch/arm/boot/dts/armada-38x-solidrun-*
+
+SOLIDRUN CUBOX-I/HUMMINGBOARD SUPPORT
+M:	Russell King <linux@armlinux.org.uk>
+S:	Maintained
+F:	arch/arm/boot/dts/imx6*-cubox-i*
+F:	arch/arm/boot/dts/imx6*-hummingboard*
+F:	arch/arm/boot/dts/imx6*-sr-*
+
 SONIC NETWORK DRIVER
 M:	Thomas Bogendoerfer <tsbogend@alpha.franken.de>
 L:	netdev@vger.kernel.org
@@ -13644,7 +13658,8 @@ S:	Supported
 F:	drivers/i2c/busses/i2c-tegra.c
 
 TEGRA IOMMU DRIVERS
-M:	Hiroshi Doyu <hdoyu@nvidia.com>
+M:	Thierry Reding <thierry.reding@gmail.com>
+L:	linux-tegra@vger.kernel.org
 S:	Supported
 F:	drivers/iommu/tegra*
 
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/Makefile linux-libre-4.16-gnu/Makefile
--- linux-libre-4.16-rc7-gnu/Makefile	2018-03-25 22:42:28.000000000 -0400
+++ linux-libre-4.16-gnu/Makefile	2018-04-01 21:16:11.000000000 -0400
@@ -2,7 +2,7 @@
 VERSION = 4
 PATCHLEVEL = 16
 SUBLEVEL = 0
-EXTRAVERSION = -rc7-gnu
+EXTRAVERSION = -gnu
 NAME = Fearless Coyote
 
 # *DOCUMENTATION*
@@ -487,6 +487,8 @@ CLANG_GCC_TC	:= --gcc-toolchain=$(GCC_TO
 endif
 KBUILD_CFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC)
 KBUILD_AFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC)
+KBUILD_CFLAGS += $(call cc-option, -no-integrated-as)
+KBUILD_AFLAGS += $(call cc-option, -no-integrated-as)
 endif
 
 RETPOLINE_CFLAGS_GCC := -mindirect-branch=thunk-extern -mindirect-branch-register
@@ -743,8 +745,6 @@ KBUILD_CFLAGS += $(call cc-disable-warni
 # See modpost pattern 2
 KBUILD_CFLAGS += $(call cc-option, -mno-global-merge,)
 KBUILD_CFLAGS += $(call cc-option, -fcatch-undefined-behavior)
-KBUILD_CFLAGS += $(call cc-option, -no-integrated-as)
-KBUILD_AFLAGS += $(call cc-option, -no-integrated-as)
 else
 
 # These warnings generated too much noise in a regular build.
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/mm/kmemleak.c linux-libre-4.16-gnu/mm/kmemleak.c
--- linux-libre-4.16-rc7-gnu/mm/kmemleak.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/mm/kmemleak.c	2018-04-01 17:20:27.000000000 -0400
@@ -1657,8 +1657,7 @@ static void start_scan_thread(void)
 }
 
 /*
- * Stop the automatic memory scanning thread. This function must be called
- * with the scan_mutex held.
+ * Stop the automatic memory scanning thread.
  */
 static void stop_scan_thread(void)
 {
@@ -1921,12 +1920,15 @@ static void kmemleak_do_cleanup(struct w
 {
 	stop_scan_thread();
 
+	mutex_lock(&scan_mutex);
 	/*
-	 * Once the scan thread has stopped, it is safe to no longer track
-	 * object freeing. Ordering of the scan thread stopping and the memory
-	 * accesses below is guaranteed by the kthread_stop() function.
+	 * Once it is made sure that kmemleak_scan has stopped, it is safe to no
+	 * longer track object freeing. Ordering of the scan thread stopping and
+	 * the memory accesses below is guaranteed by the kthread_stop()
+	 * function.
 	 */
 	kmemleak_free_enabled = 0;
+	mutex_unlock(&scan_mutex);
 
 	if (!kmemleak_found_leaks)
 		__kmemleak_do_cleanup();
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/mm/memcontrol.c linux-libre-4.16-gnu/mm/memcontrol.c
--- linux-libre-4.16-rc7-gnu/mm/memcontrol.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/mm/memcontrol.c	2018-04-01 17:20:27.000000000 -0400
@@ -714,9 +714,9 @@ static struct mem_cgroup *get_mem_cgroup
  * invocations for reference counting, or use mem_cgroup_iter_break()
  * to cancel a hierarchy walk before the round-trip is complete.
  *
- * Reclaimers can specify a zone and a priority level in @reclaim to
+ * Reclaimers can specify a node and a priority level in @reclaim to
  * divide up the memcgs in the hierarchy among all concurrent
- * reclaimers operating on the same zone and priority.
+ * reclaimers operating on the same node and priority.
  */
 struct mem_cgroup *mem_cgroup_iter(struct mem_cgroup *root,
 				   struct mem_cgroup *prev,
@@ -2299,7 +2299,7 @@ void memcg_kmem_put_cache(struct kmem_ca
 }
 
 /**
- * memcg_kmem_charge: charge a kmem page
+ * memcg_kmem_charge_memcg: charge a kmem page
  * @page: page to charge
  * @gfp: reclaim mode
  * @order: allocation order
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/mm/page_owner.c linux-libre-4.16-gnu/mm/page_owner.c
--- linux-libre-4.16-rc7-gnu/mm/page_owner.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/mm/page_owner.c	2018-04-01 17:20:27.000000000 -0400
@@ -123,13 +123,13 @@ void __reset_page_owner(struct page *pag
 static inline bool check_recursive_alloc(struct stack_trace *trace,
 					unsigned long ip)
 {
-	int i, count;
+	int i;
 
 	if (!trace->nr_entries)
 		return false;
 
-	for (i = 0, count = 0; i < trace->nr_entries; i++) {
-		if (trace->entries[i] == ip && ++count == 2)
+	for (i = 0; i < trace->nr_entries; i++) {
+		if (trace->entries[i] == ip)
 			return true;
 	}
 
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/mm/slab.c linux-libre-4.16-gnu/mm/slab.c
--- linux-libre-4.16-rc7-gnu/mm/slab.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/mm/slab.c	2018-04-01 17:20:27.000000000 -0400
@@ -1283,6 +1283,7 @@ void __init kmem_cache_init(void)
 				  nr_node_ids * sizeof(struct kmem_cache_node *),
 				  SLAB_HWCACHE_ALIGN, 0, 0);
 	list_add(&kmem_cache->list, &slab_caches);
+	memcg_link_cache(kmem_cache);
 	slab_state = PARTIAL;
 
 	/*
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/mm/vmstat.c linux-libre-4.16-gnu/mm/vmstat.c
--- linux-libre-4.16-rc7-gnu/mm/vmstat.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/mm/vmstat.c	2018-04-01 17:20:27.000000000 -0400
@@ -1839,9 +1839,11 @@ static void vmstat_update(struct work_st
 		 * to occur in the future. Keep on running the
 		 * update worker thread.
 		 */
+		preempt_disable();
 		queue_delayed_work_on(smp_processor_id(), mm_percpu_wq,
 				this_cpu_ptr(&vmstat_work),
 				round_jiffies_relative(sysctl_stat_interval));
+		preempt_enable();
 	}
 }
 
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/net/batman-adv/gateway_client.c linux-libre-4.16-gnu/net/batman-adv/gateway_client.c
--- linux-libre-4.16-rc7-gnu/net/batman-adv/gateway_client.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/net/batman-adv/gateway_client.c	2018-04-01 17:20:27.000000000 -0400
@@ -746,7 +746,7 @@ bool batadv_gw_out_of_range(struct batad
 {
 	struct batadv_neigh_node *neigh_curr = NULL;
 	struct batadv_neigh_node *neigh_old = NULL;
-	struct batadv_orig_node *orig_dst_node;
+	struct batadv_orig_node *orig_dst_node = NULL;
 	struct batadv_gw_node *gw_node = NULL;
 	struct batadv_gw_node *curr_gw = NULL;
 	struct batadv_neigh_ifinfo *curr_ifinfo, *old_ifinfo;
@@ -757,6 +757,9 @@ bool batadv_gw_out_of_range(struct batad
 
 	vid = batadv_get_vid(skb, 0);
 
+	if (is_multicast_ether_addr(ethhdr->h_dest))
+		goto out;
+
 	orig_dst_node = batadv_transtable_search(bat_priv, ethhdr->h_source,
 						 ethhdr->h_dest, vid);
 	if (!orig_dst_node)
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/net/batman-adv/multicast.c linux-libre-4.16-gnu/net/batman-adv/multicast.c
--- linux-libre-4.16-rc7-gnu/net/batman-adv/multicast.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/net/batman-adv/multicast.c	2018-04-01 17:20:27.000000000 -0400
@@ -814,8 +814,8 @@ static struct batadv_orig_node *
 batadv_mcast_forw_tt_node_get(struct batadv_priv *bat_priv,
 			      struct ethhdr *ethhdr)
 {
-	return batadv_transtable_search(bat_priv, ethhdr->h_source,
-					ethhdr->h_dest, BATADV_NO_FLAGS);
+	return batadv_transtable_search(bat_priv, NULL, ethhdr->h_dest,
+					BATADV_NO_FLAGS);
 }
 
 /**
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/net/core/dev.c linux-libre-4.16-gnu/net/core/dev.c
--- linux-libre-4.16-rc7-gnu/net/core/dev.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/net/core/dev.c	2018-04-01 17:20:27.000000000 -0400
@@ -2735,7 +2735,7 @@ __be16 skb_network_protocol(struct sk_bu
 		if (unlikely(!pskb_may_pull(skb, sizeof(struct ethhdr))))
 			return 0;
 
-		eth = (struct ethhdr *)skb_mac_header(skb);
+		eth = (struct ethhdr *)skb->data;
 		type = eth->h_proto;
 	}
 
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/net/core/skbuff.c linux-libre-4.16-gnu/net/core/skbuff.c
--- linux-libre-4.16-rc7-gnu/net/core/skbuff.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/net/core/skbuff.c	2018-04-01 17:20:27.000000000 -0400
@@ -5028,8 +5028,10 @@ static struct sk_buff *skb_reorder_vlan_
 	}
 
 	mac_len = skb->data - skb_mac_header(skb);
-	memmove(skb_mac_header(skb) + VLAN_HLEN, skb_mac_header(skb),
-		mac_len - VLAN_HLEN - ETH_TLEN);
+	if (likely(mac_len > VLAN_HLEN + ETH_TLEN)) {
+		memmove(skb_mac_header(skb) + VLAN_HLEN, skb_mac_header(skb),
+			mac_len - VLAN_HLEN - ETH_TLEN);
+	}
 	skb->mac_header += VLAN_HLEN;
 	return skb;
 }
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/net/ipv4/ip_tunnel.c linux-libre-4.16-gnu/net/ipv4/ip_tunnel.c
--- linux-libre-4.16-rc7-gnu/net/ipv4/ip_tunnel.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/net/ipv4/ip_tunnel.c	2018-04-01 17:20:27.000000000 -0400
@@ -362,13 +362,18 @@ static struct ip_tunnel *ip_tunnel_creat
 	struct ip_tunnel *nt;
 	struct net_device *dev;
 	int t_hlen;
+	int mtu;
+	int err;
 
 	BUG_ON(!itn->fb_tunnel_dev);
 	dev = __ip_tunnel_create(net, itn->fb_tunnel_dev->rtnl_link_ops, parms);
 	if (IS_ERR(dev))
 		return ERR_CAST(dev);
 
-	dev->mtu = ip_tunnel_bind_dev(dev);
+	mtu = ip_tunnel_bind_dev(dev);
+	err = dev_set_mtu(dev, mtu);
+	if (err)
+		goto err_dev_set_mtu;
 
 	nt = netdev_priv(dev);
 	t_hlen = nt->hlen + sizeof(struct iphdr);
@@ -376,6 +381,10 @@ static struct ip_tunnel *ip_tunnel_creat
 	dev->max_mtu = 0xFFF8 - dev->hard_header_len - t_hlen;
 	ip_tunnel_add(itn, nt);
 	return nt;
+
+err_dev_set_mtu:
+	unregister_netdevice(dev);
+	return ERR_PTR(err);
 }
 
 int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
@@ -1102,17 +1111,29 @@ int ip_tunnel_newlink(struct net_device
 	nt->fwmark = fwmark;
 	err = register_netdevice(dev);
 	if (err)
-		goto out;
+		goto err_register_netdevice;
 
 	if (dev->type == ARPHRD_ETHER && !tb[IFLA_ADDRESS])
 		eth_hw_addr_random(dev);
 
 	mtu = ip_tunnel_bind_dev(dev);
-	if (!tb[IFLA_MTU])
-		dev->mtu = mtu;
+	if (tb[IFLA_MTU]) {
+		unsigned int max = 0xfff8 - dev->hard_header_len - nt->hlen;
+
+		mtu = clamp(dev->mtu, (unsigned int)ETH_MIN_MTU,
+			    (unsigned int)(max - sizeof(struct iphdr)));
+	}
+
+	err = dev_set_mtu(dev, mtu);
+	if (err)
+		goto err_dev_set_mtu;
 
 	ip_tunnel_add(itn, nt);
-out:
+	return 0;
+
+err_dev_set_mtu:
+	unregister_netdevice(dev);
+err_register_netdevice:
 	return err;
 }
 EXPORT_SYMBOL_GPL(ip_tunnel_newlink);
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/net/ipv4/ip_vti.c linux-libre-4.16-gnu/net/ipv4/ip_vti.c
--- linux-libre-4.16-rc7-gnu/net/ipv4/ip_vti.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/net/ipv4/ip_vti.c	2018-04-01 17:20:27.000000000 -0400
@@ -387,8 +387,6 @@ static int vti_tunnel_init(struct net_de
 	memcpy(dev->dev_addr, &iph->saddr, 4);
 	memcpy(dev->broadcast, &iph->daddr, 4);
 
-	dev->hard_header_len	= LL_MAX_HEADER + sizeof(struct iphdr);
-	dev->mtu		= ETH_DATA_LEN;
 	dev->flags		= IFF_NOARP;
 	dev->addr_len		= 4;
 	dev->features		|= NETIF_F_LLTX;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/net/ipv4/netfilter/Makefile linux-libre-4.16-gnu/net/ipv4/netfilter/Makefile
--- linux-libre-4.16-rc7-gnu/net/ipv4/netfilter/Makefile	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/net/ipv4/netfilter/Makefile	2018-04-01 17:20:27.000000000 -0400
@@ -29,7 +29,7 @@ obj-$(CONFIG_NF_NAT_H323) += nf_nat_h323
 obj-$(CONFIG_NF_NAT_PPTP) += nf_nat_pptp.o
 
 nf_nat_snmp_basic-y := nf_nat_snmp_basic-asn1.o nf_nat_snmp_basic_main.o
-nf_nat_snmp_basic-y : nf_nat_snmp_basic-asn1.h nf_nat_snmp_basic-asn1.c
+$(obj)/nf_nat_snmp_basic_main.o: $(obj)/nf_nat_snmp_basic-asn1.h
 obj-$(CONFIG_NF_NAT_SNMP_BASIC) += nf_nat_snmp_basic.o
 clean-files := nf_nat_snmp_basic-asn1.c nf_nat_snmp_basic-asn1.h
 
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c linux-libre-4.16-gnu/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
--- linux-libre-4.16-rc7-gnu/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c	2018-04-01 17:20:27.000000000 -0400
@@ -154,8 +154,20 @@ static unsigned int ipv4_conntrack_local
 					 struct sk_buff *skb,
 					 const struct nf_hook_state *state)
 {
-	if (ip_is_fragment(ip_hdr(skb))) /* IP_NODEFRAG setsockopt set */
+	if (ip_is_fragment(ip_hdr(skb))) { /* IP_NODEFRAG setsockopt set */
+		enum ip_conntrack_info ctinfo;
+		struct nf_conn *tmpl;
+
+		tmpl = nf_ct_get(skb, &ctinfo);
+		if (tmpl && nf_ct_is_template(tmpl)) {
+			/* when skipping ct, clear templates to avoid fooling
+			 * later targets/matches
+			 */
+			skb->_nfct = 0;
+			nf_ct_put(tmpl);
+		}
 		return NF_ACCEPT;
+	}
 
 	return nf_conntrack_in(state->net, PF_INET, state->hook, skb);
 }
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/net/ipv4/netfilter/nf_socket_ipv4.c linux-libre-4.16-gnu/net/ipv4/netfilter/nf_socket_ipv4.c
--- linux-libre-4.16-rc7-gnu/net/ipv4/netfilter/nf_socket_ipv4.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/net/ipv4/netfilter/nf_socket_ipv4.c	2018-04-01 17:20:27.000000000 -0400
@@ -108,10 +108,12 @@ struct sock *nf_sk_lookup_slow_v4(struct
 	int doff = 0;
 
 	if (iph->protocol == IPPROTO_UDP || iph->protocol == IPPROTO_TCP) {
-		struct udphdr _hdr, *hp;
+		struct tcphdr _hdr;
+		struct udphdr *hp;
 
 		hp = skb_header_pointer(skb, ip_hdrlen(skb),
-					sizeof(_hdr), &_hdr);
+					iph->protocol == IPPROTO_UDP ?
+					sizeof(*hp) : sizeof(_hdr), &_hdr);
 		if (hp == NULL)
 			return NULL;
 
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/net/ipv4/syncookies.c linux-libre-4.16-gnu/net/ipv4/syncookies.c
--- linux-libre-4.16-rc7-gnu/net/ipv4/syncookies.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/net/ipv4/syncookies.c	2018-04-01 17:20:27.000000000 -0400
@@ -349,6 +349,8 @@ struct sock *cookie_v4_check(struct sock
 	req->ts_recent		= tcp_opt.saw_tstamp ? tcp_opt.rcv_tsval : 0;
 	treq->snt_synack	= 0;
 	treq->tfo_listener	= false;
+	if (IS_ENABLED(CONFIG_SMC))
+		ireq->smc_ok = 0;
 
 	ireq->ir_iif = inet_request_bound_dev_if(sk, skb);
 
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/net/ipv4/tcp_input.c linux-libre-4.16-gnu/net/ipv4/tcp_input.c
--- linux-libre-4.16-rc7-gnu/net/ipv4/tcp_input.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/net/ipv4/tcp_input.c	2018-04-01 17:20:27.000000000 -0400
@@ -6256,6 +6256,9 @@ int tcp_conn_request(struct request_sock
 	if (want_cookie && !tmp_opt.saw_tstamp)
 		tcp_clear_options(&tmp_opt);
 
+	if (IS_ENABLED(CONFIG_SMC) && want_cookie)
+		tmp_opt.smc_ok = 0;
+
 	tmp_opt.tstamp_ok = tmp_opt.saw_tstamp;
 	tcp_openreq_init(req, &tmp_opt, skb, sk);
 	inet_rsk(req)->no_srccheck = inet_sk(sk)->transparent;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/net/ipv6/ip6_output.c linux-libre-4.16-gnu/net/ipv6/ip6_output.c
--- linux-libre-4.16-rc7-gnu/net/ipv6/ip6_output.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/net/ipv6/ip6_output.c	2018-04-01 17:20:27.000000000 -0400
@@ -1246,7 +1246,7 @@ static int __ip6_append_data(struct sock
 			     const struct sockcm_cookie *sockc)
 {
 	struct sk_buff *skb, *skb_prev = NULL;
-	unsigned int maxfraglen, fragheaderlen, mtu, orig_mtu;
+	unsigned int maxfraglen, fragheaderlen, mtu, orig_mtu, pmtu;
 	int exthdrlen = 0;
 	int dst_exthdrlen = 0;
 	int hh_len;
@@ -1282,6 +1282,12 @@ static int __ip6_append_data(struct sock
 		      sizeof(struct frag_hdr) : 0) +
 		     rt->rt6i_nfheader_len;
 
+	/* as per RFC 7112 section 5, the entire IPv6 Header Chain must fit
+	 * the first fragment
+	 */
+	if (headersize + transhdrlen > mtu)
+		goto emsgsize;
+
 	if (cork->length + length > mtu - headersize && ipc6->dontfrag &&
 	    (sk->sk_protocol == IPPROTO_UDP ||
 	     sk->sk_protocol == IPPROTO_RAW)) {
@@ -1297,9 +1303,8 @@ static int __ip6_append_data(struct sock
 
 	if (cork->length + length > maxnonfragsize - headersize) {
 emsgsize:
-		ipv6_local_error(sk, EMSGSIZE, fl6,
-				 mtu - headersize +
-				 sizeof(struct ipv6hdr));
+		pmtu = max_t(int, mtu - headersize + sizeof(struct ipv6hdr), 0);
+		ipv6_local_error(sk, EMSGSIZE, fl6, pmtu);
 		return -EMSGSIZE;
 	}
 
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/net/ipv6/ip6_vti.c linux-libre-4.16-gnu/net/ipv6/ip6_vti.c
--- linux-libre-4.16-rc7-gnu/net/ipv6/ip6_vti.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/net/ipv6/ip6_vti.c	2018-04-01 17:20:27.000000000 -0400
@@ -622,11 +622,12 @@ static int vti6_err(struct sk_buff *skb,
 	return 0;
 }
 
-static void vti6_link_config(struct ip6_tnl *t)
+static void vti6_link_config(struct ip6_tnl *t, bool keep_mtu)
 {
 	struct net_device *dev = t->dev;
 	struct __ip6_tnl_parm *p = &t->parms;
 	struct net_device *tdev = NULL;
+	int mtu;
 
 	memcpy(dev->dev_addr, &p->laddr, sizeof(struct in6_addr));
 	memcpy(dev->broadcast, &p->raddr, sizeof(struct in6_addr));
@@ -640,6 +641,11 @@ static void vti6_link_config(struct ip6_
 	else
 		dev->flags &= ~IFF_POINTOPOINT;
 
+	if (keep_mtu && dev->mtu) {
+		dev->mtu = clamp(dev->mtu, dev->min_mtu, dev->max_mtu);
+		return;
+	}
+
 	if (p->flags & IP6_TNL_F_CAP_XMIT) {
 		int strict = (ipv6_addr_type(&p->raddr) &
 			      (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL));
@@ -656,20 +662,25 @@ static void vti6_link_config(struct ip6_
 		tdev = __dev_get_by_index(t->net, p->link);
 
 	if (tdev)
-		dev->mtu = max_t(int, tdev->mtu - dev->hard_header_len,
-				 IPV6_MIN_MTU);
+		mtu = tdev->mtu - sizeof(struct ipv6hdr);
+	else
+		mtu = ETH_DATA_LEN - LL_MAX_HEADER - sizeof(struct ipv6hdr);
+
+	dev->mtu = max_t(int, mtu, IPV6_MIN_MTU);
 }
 
 /**
  * vti6_tnl_change - update the tunnel parameters
  *   @t: tunnel to be changed
  *   @p: tunnel configuration parameters
+ *   @keep_mtu: MTU was set from userspace, don't re-compute it
  *
  * Description:
  *   vti6_tnl_change() updates the tunnel parameters
  **/
 static int
-vti6_tnl_change(struct ip6_tnl *t, const struct __ip6_tnl_parm *p)
+vti6_tnl_change(struct ip6_tnl *t, const struct __ip6_tnl_parm *p,
+		bool keep_mtu)
 {
 	t->parms.laddr = p->laddr;
 	t->parms.raddr = p->raddr;
@@ -679,11 +690,12 @@ vti6_tnl_change(struct ip6_tnl *t, const
 	t->parms.proto = p->proto;
 	t->parms.fwmark = p->fwmark;
 	dst_cache_reset(&t->dst_cache);
-	vti6_link_config(t);
+	vti6_link_config(t, keep_mtu);
 	return 0;
 }
 
-static int vti6_update(struct ip6_tnl *t, struct __ip6_tnl_parm *p)
+static int vti6_update(struct ip6_tnl *t, struct __ip6_tnl_parm *p,
+		       bool keep_mtu)
 {
 	struct net *net = dev_net(t->dev);
 	struct vti6_net *ip6n = net_generic(net, vti6_net_id);
@@ -691,7 +703,7 @@ static int vti6_update(struct ip6_tnl *t
 
 	vti6_tnl_unlink(ip6n, t);
 	synchronize_net();
-	err = vti6_tnl_change(t, p);
+	err = vti6_tnl_change(t, p, keep_mtu);
 	vti6_tnl_link(ip6n, t);
 	netdev_state_change(t->dev);
 	return err;
@@ -804,7 +816,7 @@ vti6_ioctl(struct net_device *dev, struc
 			} else
 				t = netdev_priv(dev);
 
-			err = vti6_update(t, &p1);
+			err = vti6_update(t, &p1, false);
 		}
 		if (t) {
 			err = 0;
@@ -866,10 +878,8 @@ static void vti6_dev_setup(struct net_de
 	dev->priv_destructor = vti6_dev_free;
 
 	dev->type = ARPHRD_TUNNEL6;
-	dev->hard_header_len = LL_MAX_HEADER + sizeof(struct ipv6hdr);
-	dev->mtu = ETH_DATA_LEN;
 	dev->min_mtu = IPV6_MIN_MTU;
-	dev->max_mtu = IP_MAX_MTU;
+	dev->max_mtu = IP_MAX_MTU - sizeof(struct ipv6hdr);
 	dev->flags |= IFF_NOARP;
 	dev->addr_len = sizeof(struct in6_addr);
 	netif_keep_dst(dev);
@@ -905,7 +915,7 @@ static int vti6_dev_init(struct net_devi
 
 	if (err)
 		return err;
-	vti6_link_config(t);
+	vti6_link_config(t, true);
 	return 0;
 }
 
@@ -1010,7 +1020,7 @@ static int vti6_changelink(struct net_de
 	} else
 		t = netdev_priv(dev);
 
-	return vti6_update(t, &p);
+	return vti6_update(t, &p, tb && tb[IFLA_MTU]);
 }
 
 static size_t vti6_get_size(const struct net_device *dev)
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/net/ipv6/netfilter/nf_socket_ipv6.c linux-libre-4.16-gnu/net/ipv6/netfilter/nf_socket_ipv6.c
--- linux-libre-4.16-rc7-gnu/net/ipv6/netfilter/nf_socket_ipv6.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/net/ipv6/netfilter/nf_socket_ipv6.c	2018-04-01 17:20:27.000000000 -0400
@@ -116,9 +116,11 @@ struct sock *nf_sk_lookup_slow_v6(struct
 	}
 
 	if (tproto == IPPROTO_UDP || tproto == IPPROTO_TCP) {
-		struct udphdr _hdr, *hp;
+		struct tcphdr _hdr;
+		struct udphdr *hp;
 
-		hp = skb_header_pointer(skb, thoff, sizeof(_hdr), &_hdr);
+		hp = skb_header_pointer(skb, thoff, tproto == IPPROTO_UDP ?
+					sizeof(*hp) : sizeof(_hdr), &_hdr);
 		if (hp == NULL)
 			return NULL;
 
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/net/ipv6/route.c linux-libre-4.16-gnu/net/ipv6/route.c
--- linux-libre-4.16-rc7-gnu/net/ipv6/route.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/net/ipv6/route.c	2018-04-01 17:20:27.000000000 -0400
@@ -919,6 +919,9 @@ static struct rt6_info *ip6_pol_route_lo
 	struct rt6_info *rt, *rt_cache;
 	struct fib6_node *fn;
 
+	if (fl6->flowi6_flags & FLOWI_FLAG_SKIP_NH_OIF)
+		flags &= ~RT6_LOOKUP_F_IFACE;
+
 	rcu_read_lock();
 	fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr);
 restart:
@@ -1626,11 +1629,10 @@ static void rt6_age_examine_exception(st
 		struct neighbour *neigh;
 		__u8 neigh_flags = 0;
 
-		neigh = dst_neigh_lookup(&rt->dst, &rt->rt6i_gateway);
-		if (neigh) {
+		neigh = __ipv6_neigh_lookup_noref(rt->dst.dev, &rt->rt6i_gateway);
+		if (neigh)
 			neigh_flags = neigh->flags;
-			neigh_release(neigh);
-		}
+
 		if (!(neigh_flags & NTF_ROUTER)) {
 			RT6_TRACE("purging route %p via non-router but gateway\n",
 				  rt);
@@ -1654,7 +1656,8 @@ void rt6_age_exceptions(struct rt6_info
 	if (!rcu_access_pointer(rt->rt6i_exception_bucket))
 		return;
 
-	spin_lock_bh(&rt6_exception_lock);
+	rcu_read_lock_bh();
+	spin_lock(&rt6_exception_lock);
 	bucket = rcu_dereference_protected(rt->rt6i_exception_bucket,
 				    lockdep_is_held(&rt6_exception_lock));
 
@@ -1668,7 +1671,8 @@ void rt6_age_exceptions(struct rt6_info
 			bucket++;
 		}
 	}
-	spin_unlock_bh(&rt6_exception_lock);
+	spin_unlock(&rt6_exception_lock);
+	rcu_read_unlock_bh();
 }
 
 struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/net/ipv6/seg6_iptunnel.c linux-libre-4.16-gnu/net/ipv6/seg6_iptunnel.c
--- linux-libre-4.16-rc7-gnu/net/ipv6/seg6_iptunnel.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/net/ipv6/seg6_iptunnel.c	2018-04-01 17:20:27.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/net.h>
 #include <linux/module.h>
 #include <net/ip.h>
+#include <net/ip_tunnels.h>
 #include <net/lwtunnel.h>
 #include <net/netevent.h>
 #include <net/netns/generic.h>
@@ -211,11 +212,6 @@ static int seg6_do_srh(struct sk_buff *s
 
 	tinfo = seg6_encap_lwtunnel(dst->lwtstate);
 
-	if (likely(!skb->encapsulation)) {
-		skb_reset_inner_headers(skb);
-		skb->encapsulation = 1;
-	}
-
 	switch (tinfo->mode) {
 	case SEG6_IPTUN_MODE_INLINE:
 		if (skb->protocol != htons(ETH_P_IPV6))
@@ -224,10 +220,12 @@ static int seg6_do_srh(struct sk_buff *s
 		err = seg6_do_srh_inline(skb, tinfo->srh);
 		if (err)
 			return err;
-
-		skb_reset_inner_headers(skb);
 		break;
 	case SEG6_IPTUN_MODE_ENCAP:
+		err = iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6);
+		if (err)
+			return err;
+
 		if (skb->protocol == htons(ETH_P_IPV6))
 			proto = IPPROTO_IPV6;
 		else if (skb->protocol == htons(ETH_P_IP))
@@ -239,6 +237,8 @@ static int seg6_do_srh(struct sk_buff *s
 		if (err)
 			return err;
 
+		skb_set_inner_transport_header(skb, skb_transport_offset(skb));
+		skb_set_inner_protocol(skb, skb->protocol);
 		skb->protocol = htons(ETH_P_IPV6);
 		break;
 	case SEG6_IPTUN_MODE_L2ENCAP:
@@ -262,8 +262,6 @@ static int seg6_do_srh(struct sk_buff *s
 	ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
 	skb_set_transport_header(skb, sizeof(struct ipv6hdr));
 
-	skb_set_inner_protocol(skb, skb->protocol);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/net/ipv6/syncookies.c linux-libre-4.16-gnu/net/ipv6/syncookies.c
--- linux-libre-4.16-rc7-gnu/net/ipv6/syncookies.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/net/ipv6/syncookies.c	2018-04-01 17:20:27.000000000 -0400
@@ -217,6 +217,8 @@ struct sock *cookie_v6_check(struct sock
 	treq->snt_isn = cookie;
 	treq->ts_off = 0;
 	treq->txhash = net_tx_rndhash();
+	if (IS_ENABLED(CONFIG_SMC))
+		ireq->smc_ok = 0;
 
 	/*
 	 * We need to lookup the dst_entry to get the correct window size.
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/net/llc/llc_c_ac.c linux-libre-4.16-gnu/net/llc/llc_c_ac.c
--- linux-libre-4.16-rc7-gnu/net/llc/llc_c_ac.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/net/llc/llc_c_ac.c	2018-04-01 17:20:27.000000000 -0400
@@ -389,7 +389,7 @@ static int llc_conn_ac_send_i_cmd_p_set_
 	llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR);
 	rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
 	if (likely(!rc)) {
-		llc_conn_send_pdu(sk, skb);
+		rc = llc_conn_send_pdu(sk, skb);
 		llc_conn_ac_inc_vs_by_1(sk, skb);
 	}
 	return rc;
@@ -916,7 +916,7 @@ static int llc_conn_ac_send_i_rsp_f_set_
 	llc_pdu_init_as_i_cmd(skb, llc->ack_pf, llc->vS, llc->vR);
 	rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
 	if (likely(!rc)) {
-		llc_conn_send_pdu(sk, skb);
+		rc = llc_conn_send_pdu(sk, skb);
 		llc_conn_ac_inc_vs_by_1(sk, skb);
 	}
 	return rc;
@@ -935,14 +935,17 @@ static int llc_conn_ac_send_i_rsp_f_set_
 int llc_conn_ac_send_i_as_ack(struct sock *sk, struct sk_buff *skb)
 {
 	struct llc_sock *llc = llc_sk(sk);
+	int ret;
 
 	if (llc->ack_must_be_send) {
-		llc_conn_ac_send_i_rsp_f_set_ackpf(sk, skb);
+		ret = llc_conn_ac_send_i_rsp_f_set_ackpf(sk, skb);
 		llc->ack_must_be_send = 0 ;
 		llc->ack_pf = 0;
-	} else
-		llc_conn_ac_send_i_cmd_p_set_0(sk, skb);
-	return 0;
+	} else {
+		ret = llc_conn_ac_send_i_cmd_p_set_0(sk, skb);
+	}
+
+	return ret;
 }
 
 /**
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/net/llc/llc_conn.c linux-libre-4.16-gnu/net/llc/llc_conn.c
--- linux-libre-4.16-rc7-gnu/net/llc/llc_conn.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/net/llc/llc_conn.c	2018-04-01 17:20:27.000000000 -0400
@@ -30,7 +30,7 @@
 #endif
 
 static int llc_find_offset(int state, int ev_type);
-static void llc_conn_send_pdus(struct sock *sk);
+static int llc_conn_send_pdus(struct sock *sk, struct sk_buff *skb);
 static int llc_conn_service(struct sock *sk, struct sk_buff *skb);
 static int llc_exec_conn_trans_actions(struct sock *sk,
 				       struct llc_conn_state_trans *trans,
@@ -193,11 +193,11 @@ out_skb_put:
 	return rc;
 }
 
-void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb)
+int llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb)
 {
 	/* queue PDU to send to MAC layer */
 	skb_queue_tail(&sk->sk_write_queue, skb);
-	llc_conn_send_pdus(sk);
+	return llc_conn_send_pdus(sk, skb);
 }
 
 /**
@@ -255,7 +255,7 @@ void llc_conn_resend_i_pdu_as_cmd(struct
 	if (howmany_resend > 0)
 		llc->vS = (llc->vS + 1) % LLC_2_SEQ_NBR_MODULO;
 	/* any PDUs to re-send are queued up; start sending to MAC */
-	llc_conn_send_pdus(sk);
+	llc_conn_send_pdus(sk, NULL);
 out:;
 }
 
@@ -296,7 +296,7 @@ void llc_conn_resend_i_pdu_as_rsp(struct
 	if (howmany_resend > 0)
 		llc->vS = (llc->vS + 1) % LLC_2_SEQ_NBR_MODULO;
 	/* any PDUs to re-send are queued up; start sending to MAC */
-	llc_conn_send_pdus(sk);
+	llc_conn_send_pdus(sk, NULL);
 out:;
 }
 
@@ -340,12 +340,16 @@ out:
 /**
  *	llc_conn_send_pdus - Sends queued PDUs
  *	@sk: active connection
+ *	@hold_skb: the skb held by caller, or NULL if does not care
  *
- *	Sends queued pdus to MAC layer for transmission.
+ *	Sends queued pdus to MAC layer for transmission. When @hold_skb is
+ *	NULL, always return 0. Otherwise, return 0 if @hold_skb is sent
+ *	successfully, or 1 for failure.
  */
-static void llc_conn_send_pdus(struct sock *sk)
+static int llc_conn_send_pdus(struct sock *sk, struct sk_buff *hold_skb)
 {
 	struct sk_buff *skb;
+	int ret = 0;
 
 	while ((skb = skb_dequeue(&sk->sk_write_queue)) != NULL) {
 		struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
@@ -357,10 +361,20 @@ static void llc_conn_send_pdus(struct so
 			skb_queue_tail(&llc_sk(sk)->pdu_unack_q, skb);
 			if (!skb2)
 				break;
-			skb = skb2;
+			dev_queue_xmit(skb2);
+		} else {
+			bool is_target = skb == hold_skb;
+			int rc;
+
+			if (is_target)
+				skb_get(skb);
+			rc = dev_queue_xmit(skb);
+			if (is_target)
+				ret = rc;
 		}
-		dev_queue_xmit(skb);
 	}
+
+	return ret;
 }
 
 /**
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/net/netfilter/nf_tables_api.c linux-libre-4.16-gnu/net/netfilter/nf_tables_api.c
--- linux-libre-4.16-rc7-gnu/net/netfilter/nf_tables_api.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/net/netfilter/nf_tables_api.c	2018-04-01 17:20:27.000000000 -0400
@@ -74,15 +74,77 @@ static void nft_trans_destroy(struct nft
 	kfree(trans);
 }
 
+/* removal requests are queued in the commit_list, but not acted upon
+ * until after all new rules are in place.
+ *
+ * Therefore, nf_register_net_hook(net, &nat_hook) runs before pending
+ * nf_unregister_net_hook().
+ *
+ * nf_register_net_hook thus fails if a nat hook is already in place
+ * even if the conflicting hook is about to be removed.
+ *
+ * If collision is detected, search commit_log for DELCHAIN matching
+ * the new nat hooknum; if we find one collision is temporary:
+ *
+ * Either transaction is aborted (new/colliding hook is removed), or
+ * transaction is committed (old hook is removed).
+ */
+static bool nf_tables_allow_nat_conflict(const struct net *net,
+					 const struct nf_hook_ops *ops)
+{
+	const struct nft_trans *trans;
+	bool ret = false;
+
+	if (!ops->nat_hook)
+		return false;
+
+	list_for_each_entry(trans, &net->nft.commit_list, list) {
+		const struct nf_hook_ops *pending_ops;
+		const struct nft_chain *pending;
+
+		if (trans->msg_type != NFT_MSG_NEWCHAIN &&
+		    trans->msg_type != NFT_MSG_DELCHAIN)
+			continue;
+
+		pending = trans->ctx.chain;
+		if (!nft_is_base_chain(pending))
+			continue;
+
+		pending_ops = &nft_base_chain(pending)->ops;
+		if (pending_ops->nat_hook &&
+		    pending_ops->pf == ops->pf &&
+		    pending_ops->hooknum == ops->hooknum) {
+			/* other hook registration already pending? */
+			if (trans->msg_type == NFT_MSG_NEWCHAIN)
+				return false;
+
+			ret = true;
+		}
+	}
+
+	return ret;
+}
+
 static int nf_tables_register_hook(struct net *net,
 				   const struct nft_table *table,
 				   struct nft_chain *chain)
 {
+	struct nf_hook_ops *ops;
+	int ret;
+
 	if (table->flags & NFT_TABLE_F_DORMANT ||
 	    !nft_is_base_chain(chain))
 		return 0;
 
-	return nf_register_net_hook(net, &nft_base_chain(chain)->ops);
+	ops = &nft_base_chain(chain)->ops;
+	ret = nf_register_net_hook(net, ops);
+	if (ret == -EBUSY && nf_tables_allow_nat_conflict(net, ops)) {
+		ops->nat_hook = false;
+		ret = nf_register_net_hook(net, ops);
+		ops->nat_hook = true;
+	}
+
+	return ret;
 }
 
 static void nf_tables_unregister_hook(struct net *net,
@@ -1226,8 +1288,6 @@ static void nf_tables_chain_destroy(stru
 		free_percpu(basechain->stats);
 		if (basechain->stats)
 			static_branch_dec(&nft_counters_enabled);
-		if (basechain->ops.dev != NULL)
-			dev_put(basechain->ops.dev);
 		kfree(chain->name);
 		kfree(basechain);
 	} else {
@@ -1294,7 +1354,7 @@ static int nft_chain_parse_hook(struct n
 		}
 
 		nla_strlcpy(ifname, ha[NFTA_HOOK_DEV], IFNAMSIZ);
-		dev = dev_get_by_name(net, ifname);
+		dev = __dev_get_by_name(net, ifname);
 		if (!dev) {
 			module_put(type->owner);
 			return -ENOENT;
@@ -1311,8 +1371,6 @@ static int nft_chain_parse_hook(struct n
 static void nft_chain_release_hook(struct nft_chain_hook *hook)
 {
 	module_put(hook->type->owner);
-	if (hook->dev != NULL)
-		dev_put(hook->dev);
 }
 
 static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
@@ -1911,6 +1969,7 @@ static const struct nla_policy nft_rule_
 	[NFTA_RULE_POSITION]	= { .type = NLA_U64 },
 	[NFTA_RULE_USERDATA]	= { .type = NLA_BINARY,
 				    .len = NFT_USERDATA_MAXLEN },
+	[NFTA_RULE_ID]		= { .type = NLA_U32 },
 };
 
 static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net,
@@ -2446,6 +2505,9 @@ EXPORT_SYMBOL_GPL(nft_unregister_set);
 
 static bool nft_set_ops_candidate(const struct nft_set_ops *ops, u32 flags)
 {
+	if ((flags & NFT_SET_EVAL) && !ops->update)
+		return false;
+
 	return (flags & ops->features) == (flags & NFT_SET_FEATURES);
 }
 
@@ -2510,7 +2572,7 @@ nft_select_set_ops(const struct nft_ctx
 				if (est.space == best.space &&
 				    est.lookup < best.lookup)
 					break;
-			} else if (est.size < best.size) {
+			} else if (est.size < best.size || !bops) {
 				break;
 			}
 			continue;
@@ -3315,6 +3377,8 @@ static const struct nla_policy nft_set_e
 	[NFTA_SET_ELEM_TIMEOUT]		= { .type = NLA_U64 },
 	[NFTA_SET_ELEM_USERDATA]	= { .type = NLA_BINARY,
 					    .len = NFT_USERDATA_MAXLEN },
+	[NFTA_SET_ELEM_EXPR]		= { .type = NLA_NESTED },
+	[NFTA_SET_ELEM_OBJREF]		= { .type = NLA_STRING },
 };
 
 static const struct nla_policy nft_set_elem_list_policy[NFTA_SET_ELEM_LIST_MAX + 1] = {
@@ -4864,8 +4928,6 @@ nf_tables_flowtable_lookup_byhandle(cons
        return ERR_PTR(-ENOENT);
 }
 
-#define NFT_FLOWTABLE_DEVICE_MAX	8
-
 static int nf_tables_parse_devices(const struct nft_ctx *ctx,
 				   const struct nlattr *attr,
 				   struct net_device *dev_array[], int *len)
@@ -4882,7 +4944,7 @@ static int nf_tables_parse_devices(const
 		}
 
 		nla_strlcpy(ifname, tmp, IFNAMSIZ);
-		dev = dev_get_by_name(ctx->net, ifname);
+		dev = __dev_get_by_name(ctx->net, ifname);
 		if (!dev) {
 			err = -ENOENT;
 			goto err1;
@@ -4938,13 +5000,11 @@ static int nf_tables_flowtable_parse_hoo
 	err = nf_tables_parse_devices(ctx, tb[NFTA_FLOWTABLE_HOOK_DEVS],
 				      dev_array, &n);
 	if (err < 0)
-		goto err1;
+		return err;
 
 	ops = kzalloc(sizeof(struct nf_hook_ops) * n, GFP_KERNEL);
-	if (!ops) {
-		err = -ENOMEM;
-		goto err1;
-	}
+	if (!ops)
+		return -ENOMEM;
 
 	flowtable->hooknum	= hooknum;
 	flowtable->priority	= priority;
@@ -4958,13 +5018,10 @@ static int nf_tables_flowtable_parse_hoo
 		flowtable->ops[i].priv		= &flowtable->data.rhashtable;
 		flowtable->ops[i].hook		= flowtable->data.type->hook;
 		flowtable->ops[i].dev		= dev_array[i];
+		flowtable->dev_name[i]		= kstrdup(dev_array[i]->name,
+							  GFP_KERNEL);
 	}
 
-	err = 0;
-err1:
-	for (i = 0; i < n; i++)
-		dev_put(dev_array[i]);
-
 	return err;
 }
 
@@ -5135,8 +5192,10 @@ static int nf_tables_newflowtable(struct
 err5:
 	i = flowtable->ops_len;
 err4:
-	for (k = i - 1; k >= 0; k--)
+	for (k = i - 1; k >= 0; k--) {
+		kfree(flowtable->dev_name[k]);
 		nf_unregister_net_hook(net, &flowtable->ops[k]);
+	}
 
 	kfree(flowtable->ops);
 err3:
@@ -5226,9 +5285,9 @@ static int nf_tables_fill_flowtable_info
 		goto nla_put_failure;
 
 	for (i = 0; i < flowtable->ops_len; i++) {
-		if (flowtable->ops[i].dev &&
+		if (flowtable->dev_name[i][0] &&
 		    nla_put_string(skb, NFTA_DEVICE_NAME,
-				   flowtable->ops[i].dev->name))
+				   flowtable->dev_name[i]))
 			goto nla_put_failure;
 	}
 	nla_nest_end(skb, nest_devs);
@@ -5470,6 +5529,7 @@ static void nft_flowtable_event(unsigned
 			continue;
 
 		nf_unregister_net_hook(dev_net(dev), &flowtable->ops[i]);
+		flowtable->dev_name[i][0] = '\0';
 		flowtable->ops[i].dev = NULL;
 		break;
 	}
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/net/netfilter/nft_set_hash.c linux-libre-4.16-gnu/net/netfilter/nft_set_hash.c
--- linux-libre-4.16-rc7-gnu/net/netfilter/nft_set_hash.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/net/netfilter/nft_set_hash.c	2018-04-01 17:20:27.000000000 -0400
@@ -674,7 +674,7 @@ static const struct nft_set_ops *
 nft_hash_select_ops(const struct nft_ctx *ctx, const struct nft_set_desc *desc,
 		    u32 flags)
 {
-	if (desc->size && !(flags & NFT_SET_TIMEOUT)) {
+	if (desc->size && !(flags & (NFT_SET_EVAL | NFT_SET_TIMEOUT))) {
 		switch (desc->klen) {
 		case 4:
 			return &nft_hash_fast_ops;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/net/netlink/af_netlink.c linux-libre-4.16-gnu/net/netlink/af_netlink.c
--- linux-libre-4.16-rc7-gnu/net/netlink/af_netlink.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/net/netlink/af_netlink.c	2018-04-01 17:20:27.000000000 -0400
@@ -1085,6 +1085,9 @@ static int netlink_connect(struct socket
 	if (addr->sa_family != AF_NETLINK)
 		return -EINVAL;
 
+	if (alen < sizeof(struct sockaddr_nl))
+		return -EINVAL;
+
 	if ((nladdr->nl_groups || nladdr->nl_pid) &&
 	    !netlink_allowed(sock, NL_CFG_F_NONROOT_SEND))
 		return -EPERM;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/net/sched/act_api.c linux-libre-4.16-gnu/net/sched/act_api.c
--- linux-libre-4.16-rc7-gnu/net/sched/act_api.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/net/sched/act_api.c	2018-04-01 17:20:27.000000000 -0400
@@ -135,8 +135,10 @@ static int tcf_dump_walker(struct tcf_id
 			continue;
 
 		nest = nla_nest_start(skb, n_i);
-		if (!nest)
+		if (!nest) {
+			index--;
 			goto nla_put_failure;
+		}
 		err = tcf_action_dump_1(skb, p, 0, 0);
 		if (err < 0) {
 			index--;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/net/sched/sch_generic.c linux-libre-4.16-gnu/net/sched/sch_generic.c
--- linux-libre-4.16-rc7-gnu/net/sched/sch_generic.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/net/sched/sch_generic.c	2018-04-01 17:20:27.000000000 -0400
@@ -373,24 +373,33 @@ bool sch_direct_xmit(struct sk_buff *skb
  */
 static inline bool qdisc_restart(struct Qdisc *q, int *packets)
 {
+	bool more, validate, nolock = q->flags & TCQ_F_NOLOCK;
 	spinlock_t *root_lock = NULL;
 	struct netdev_queue *txq;
 	struct net_device *dev;
 	struct sk_buff *skb;
-	bool validate;
 
 	/* Dequeue packet */
+	if (nolock && test_and_set_bit(__QDISC_STATE_RUNNING, &q->state))
+		return false;
+
 	skb = dequeue_skb(q, &validate, packets);
-	if (unlikely(!skb))
+	if (unlikely(!skb)) {
+		if (nolock)
+			clear_bit(__QDISC_STATE_RUNNING, &q->state);
 		return false;
+	}
 
-	if (!(q->flags & TCQ_F_NOLOCK))
+	if (!nolock)
 		root_lock = qdisc_lock(q);
 
 	dev = qdisc_dev(q);
 	txq = skb_get_tx_queue(dev, skb);
 
-	return sch_direct_xmit(skb, q, dev, txq, root_lock, validate);
+	more = sch_direct_xmit(skb, q, dev, txq, root_lock, validate);
+	if (nolock)
+		clear_bit(__QDISC_STATE_RUNNING, &q->state);
+	return more;
 }
 
 void __qdisc_run(struct Qdisc *q)
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/net/smc/smc_clc.c linux-libre-4.16-gnu/net/smc/smc_clc.c
--- linux-libre-4.16-rc7-gnu/net/smc/smc_clc.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/net/smc/smc_clc.c	2018-04-01 17:20:27.000000000 -0400
@@ -133,7 +133,7 @@ int smc_clc_wait_msg(struct smc_sock *sm
 
 	/* receive the complete CLC message */
 	memset(&msg, 0, sizeof(struct msghdr));
-	iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC, &vec, 1, buflen);
+	iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC, &vec, 1, datlen);
 	krflags = MSG_WAITALL;
 	smc->clcsock->sk->sk_rcvtimeo = CLC_WAIT_TIME;
 	len = sock_recvmsg(smc->clcsock, &msg, krflags);
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/net/strparser/strparser.c linux-libre-4.16-gnu/net/strparser/strparser.c
--- linux-libre-4.16-rc7-gnu/net/strparser/strparser.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/net/strparser/strparser.c	2018-04-01 17:20:27.000000000 -0400
@@ -60,7 +60,7 @@ static void strp_abort_strp(struct strpa
 		struct sock *sk = strp->sk;
 
 		/* Report an error on the lower socket */
-		sk->sk_err = err;
+		sk->sk_err = -err;
 		sk->sk_error_report(sk);
 	}
 }
@@ -458,7 +458,7 @@ static void strp_msg_timeout(struct work
 	/* Message assembly timed out */
 	STRP_STATS_INCR(strp->stats.msg_timeouts);
 	strp->cb.lock(strp);
-	strp->cb.abort_parser(strp, ETIMEDOUT);
+	strp->cb.abort_parser(strp, -ETIMEDOUT);
 	strp->cb.unlock(strp);
 }
 
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/net/xfrm/xfrm_input.c linux-libre-4.16-gnu/net/xfrm/xfrm_input.c
--- linux-libre-4.16-rc7-gnu/net/xfrm/xfrm_input.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/net/xfrm/xfrm_input.c	2018-04-01 17:20:27.000000000 -0400
@@ -26,6 +26,12 @@ struct xfrm_trans_tasklet {
 };
 
 struct xfrm_trans_cb {
+	union {
+		struct inet_skb_parm	h4;
+#if IS_ENABLED(CONFIG_IPV6)
+		struct inet6_skb_parm	h6;
+#endif
+	} header;
 	int (*finish)(struct net *net, struct sock *sk, struct sk_buff *skb);
 };
 
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/net/xfrm/xfrm_output.c linux-libre-4.16-gnu/net/xfrm/xfrm_output.c
--- linux-libre-4.16-rc7-gnu/net/xfrm/xfrm_output.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/net/xfrm/xfrm_output.c	2018-04-01 17:20:27.000000000 -0400
@@ -285,8 +285,9 @@ void xfrm_local_error(struct sk_buff *sk
 		return;
 
 	afinfo = xfrm_state_get_afinfo(proto);
-	if (afinfo)
+	if (afinfo) {
 		afinfo->local_error(skb, mtu);
-	rcu_read_unlock();
+		rcu_read_unlock();
+	}
 }
 EXPORT_SYMBOL_GPL(xfrm_local_error);
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/scripts/adjust_autoksyms.sh linux-libre-4.16-gnu/scripts/adjust_autoksyms.sh
--- linux-libre-4.16-rc7-gnu/scripts/adjust_autoksyms.sh	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/scripts/adjust_autoksyms.sh	2018-04-01 17:20:27.000000000 -0400
@@ -84,6 +84,13 @@ while read sympath; do
 	depfile="include/config/ksym/${sympath}.h"
 	mkdir -p "$(dirname "$depfile")"
 	touch "$depfile"
+	# Filesystems with coarse time precision may create timestamps
+	# equal to the one from a file that was very recently built and that
+	# needs to be rebuild. Let's guard against that by making sure our
+	# dep files are always newer than the first file we created here.
+	while [ ! "$depfile" -nt "$new_ksyms_file" ]; do
+		touch "$depfile"
+	done
 	echo $((count += 1))
 done | tail -1 )
 changed=${changed:-0}
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/scripts/package/builddeb linux-libre-4.16-gnu/scripts/package/builddeb
--- linux-libre-4.16-rc7-gnu/scripts/package/builddeb	2018-03-25 22:42:29.000000000 -0400
+++ linux-libre-4.16-gnu/scripts/package/builddeb	2018-04-01 21:16:13.000000000 -0400
@@ -313,7 +313,7 @@ fi
 
 # Build kernel header package
 (cd $srctree; find . -name Makefile\* -o -name Kconfig\* -o -name \*.pl) > "$objtree/debian/hdrsrcfiles"
-(cd $srctree; find arch/*/include include scripts -type f) >> "$objtree/debian/hdrsrcfiles"
+(cd $srctree; find arch/*/include include scripts -type f -o -type l) >> "$objtree/debian/hdrsrcfiles"
 (cd $srctree; find arch/$SRCARCH -name module.lds -o -name Kbuild.platforms -o -name Platform) >> "$objtree/debian/hdrsrcfiles"
 (cd $srctree; find $(find arch/$SRCARCH -name include -o -name scripts -type d) -type f) >> "$objtree/debian/hdrsrcfiles"
 if grep -q '^CONFIG_STACK_VALIDATION=y' $KCONFIG_CONFIG ; then
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/scripts/package/mkspec linux-libre-4.16-gnu/scripts/package/mkspec
--- linux-libre-4.16-rc7-gnu/scripts/package/mkspec	2018-03-25 22:42:29.000000000 -0400
+++ linux-libre-4.16-gnu/scripts/package/mkspec	2018-04-01 21:16:13.000000000 -0400
@@ -99,7 +99,7 @@ $M	make %{?_smp_mflags} INSTALL_MOD_PATH
 $S$M	rm -f %{buildroot}/lib/modules/$KERNELRELEASE/build
 $S$M	rm -f %{buildroot}/lib/modules/$KERNELRELEASE/source
 $S$M	mkdir -p %{buildroot}/usr/src/kernels/$KERNELRELEASE
-$S$M	tar cf - . $EXCLUDES | tar xf - -C %{buildroot}/usr/src/kernels/$KERNELRELEASE
+$S$M	tar cf - $EXCLUDES . | tar xf - -C %{buildroot}/usr/src/kernels/$KERNELRELEASE
 $S$M	cd %{buildroot}/lib/modules/$KERNELRELEASE
 $S$M	ln -sf /usr/src/kernels/$KERNELRELEASE build
 $S$M	ln -sf /usr/src/kernels/$KERNELRELEASE source
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/sound/core/oss/pcm_oss.c linux-libre-4.16-gnu/sound/core/oss/pcm_oss.c
--- linux-libre-4.16-rc7-gnu/sound/core/oss/pcm_oss.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/sound/core/oss/pcm_oss.c	2018-04-01 17:20:27.000000000 -0400
@@ -1326,7 +1326,7 @@ static ssize_t snd_pcm_oss_write2(struct
 static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const char __user *buf, size_t bytes)
 {
 	size_t xfer = 0;
-	ssize_t tmp;
+	ssize_t tmp = 0;
 	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	if (atomic_read(&substream->mmap_count))
@@ -1433,7 +1433,7 @@ static ssize_t snd_pcm_oss_read2(struct
 static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream *substream, char __user *buf, size_t bytes)
 {
 	size_t xfer = 0;
-	ssize_t tmp;
+	ssize_t tmp = 0;
 	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	if (atomic_read(&substream->mmap_count))
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/sound/core/pcm_native.c linux-libre-4.16-gnu/sound/core/pcm_native.c
--- linux-libre-4.16-rc7-gnu/sound/core/pcm_native.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/sound/core/pcm_native.c	2018-04-01 17:20:27.000000000 -0400
@@ -3422,7 +3422,7 @@ int snd_pcm_lib_default_mmap(struct snd_
 					 area,
 					 substream->runtime->dma_area,
 					 substream->runtime->dma_addr,
-					 area->vm_end - area->vm_start);
+					 substream->runtime->dma_bytes);
 #endif /* CONFIG_X86 */
 	/* mmap with fault handler */
 	area->vm_ops = &snd_pcm_vm_ops_data_fault;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/sound/usb/quirks.c linux-libre-4.16-gnu/sound/usb/quirks.c
--- linux-libre-4.16-rc7-gnu/sound/usb/quirks.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/sound/usb/quirks.c	2018-04-01 17:20:27.000000000 -0400
@@ -1171,6 +1171,7 @@ static bool is_teac_dsd_dac(unsigned int
 	switch (id) {
 	case USB_ID(0x0644, 0x8043): /* TEAC UD-501/UD-503/NT-503 */
 	case USB_ID(0x0644, 0x8044): /* Esoteric D-05X */
+	case USB_ID(0x0644, 0x804a): /* TEAC UD-301 */
 		return true;
 	}
 	return false;
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/tools/bpf/bpftool/map.c linux-libre-4.16-gnu/tools/bpf/bpftool/map.c
--- linux-libre-4.16-rc7-gnu/tools/bpf/bpftool/map.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/tools/bpf/bpftool/map.c	2018-04-01 17:20:27.000000000 -0400
@@ -428,7 +428,7 @@ static int show_map_close_json(int fd, s
 		jsonw_string_field(json_wtr, "name", info->name);
 
 	jsonw_name(json_wtr, "flags");
-	jsonw_printf(json_wtr, "%#x", info->map_flags);
+	jsonw_printf(json_wtr, "%d", info->map_flags);
 
 	print_dev_json(info->ifindex, info->netns_dev, info->netns_ino);
 
diff -druNp --no-dereference linux-libre-4.16-rc7-gnu/tools/objtool/check.c linux-libre-4.16-gnu/tools/objtool/check.c
--- linux-libre-4.16-rc7-gnu/tools/objtool/check.c	2018-03-25 18:44:30.000000000 -0400
+++ linux-libre-4.16-gnu/tools/objtool/check.c	2018-04-01 17:20:27.000000000 -0400
@@ -1386,6 +1386,17 @@ static int update_insn_state(struct inst
 				state->vals[op->dest.reg].offset = -state->stack_size;
 			}
 
+			else if (op->src.reg == CFI_BP && op->dest.reg == CFI_SP &&
+				 cfa->base == CFI_BP) {
+
+				/*
+				 * mov %rbp, %rsp
+				 *
+				 * Restore the original stack pointer (Clang).
+				 */
+				state->stack_size = -state->regs[CFI_BP].offset;
+			}
+
 			else if (op->dest.reg == cfa->base) {
 
 				/* mov %reg, %rsp */
