diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/alpha/kernel/pci-sysfs.c linux-libre-4.4.223-gnu/arch/alpha/kernel/pci-sysfs.c
--- linux-libre-4.4.222-gnu/arch/alpha/kernel/pci-sysfs.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/alpha/kernel/pci-sysfs.c	2020-05-10 04:26:37.000000000 -0400
@@ -77,10 +77,10 @@ static int pci_mmap_resource(struct kobj
 	if (i >= PCI_ROM_RESOURCE)
 		return -ENODEV;
 
-	if (!__pci_mmap_fits(pdev, i, vma, sparse))
+	if (res->flags & IORESOURCE_MEM && iomem_is_exclusive(res->start))
 		return -EINVAL;
 
-	if (iomem_is_exclusive(res->start))
+	if (!__pci_mmap_fits(pdev, i, vma, sparse))
 		return -EINVAL;
 
 	pcibios_resource_to_bus(pdev->bus, &bar, res);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/arm/boot/dts/kirkwood-ds112.dts linux-libre-4.4.223-gnu/arch/arm/boot/dts/kirkwood-ds112.dts
--- linux-libre-4.4.222-gnu/arch/arm/boot/dts/kirkwood-ds112.dts	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/arm/boot/dts/kirkwood-ds112.dts	2020-05-10 04:26:37.000000000 -0400
@@ -14,7 +14,7 @@
 #include "kirkwood-synology.dtsi"
 
 / {
-	model = "Synology DS111";
+	model = "Synology DS112";
 	compatible = "synology,ds111", "marvell,kirkwood";
 
 	memory {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/arm/boot/dts/kirkwood-lswvl.dts linux-libre-4.4.223-gnu/arch/arm/boot/dts/kirkwood-lswvl.dts
--- linux-libre-4.4.222-gnu/arch/arm/boot/dts/kirkwood-lswvl.dts	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/arm/boot/dts/kirkwood-lswvl.dts	2020-05-10 04:26:37.000000000 -0400
@@ -1,7 +1,8 @@
 /*
  * Device Tree file for Buffalo Linkstation LS-WVL/VL
  *
- * Copyright (C) 2015, rogershimizu@gmail.com
+ * Copyright (C) 2015, 2016
+ * Roger Shimizu <rogershimizu@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -156,21 +157,21 @@
 		button@1 {
 			label = "Function Button";
 			linux,code = <KEY_OPTION>;
-			gpios = <&gpio0 45 GPIO_ACTIVE_LOW>;
+			gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
 		};
 
 		button@2 {
 			label = "Power-on Switch";
 			linux,code = <KEY_RESERVED>;
 			linux,input-type = <5>;
-			gpios = <&gpio0 46 GPIO_ACTIVE_LOW>;
+			gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
 		};
 
 		button@3 {
 			label = "Power-auto Switch";
 			linux,code = <KEY_ESC>;
 			linux,input-type = <5>;
-			gpios = <&gpio0 47 GPIO_ACTIVE_LOW>;
+			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
 		};
 	};
 
@@ -185,38 +186,38 @@
 
 		led@1 {
 			label = "lswvl:red:alarm";
-			gpios = <&gpio0 36 GPIO_ACTIVE_LOW>;
+			gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
 		};
 
 		led@2 {
 			label = "lswvl:red:func";
-			gpios = <&gpio0 37 GPIO_ACTIVE_LOW>;
+			gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
 		};
 
 		led@3 {
 			label = "lswvl:amber:info";
-			gpios = <&gpio0 38 GPIO_ACTIVE_LOW>;
+			gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
 		};
 
 		led@4 {
 			label = "lswvl:blue:func";
-			gpios = <&gpio0 39 GPIO_ACTIVE_LOW>;
+			gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
 		};
 
 		led@5 {
 			label = "lswvl:blue:power";
-			gpios = <&gpio0 40 GPIO_ACTIVE_LOW>;
+			gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
 			default-state = "keep";
 		};
 
 		led@6 {
 			label = "lswvl:red:hdderr0";
-			gpios = <&gpio0 34 GPIO_ACTIVE_LOW>;
+			gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
 		};
 
 		led@7 {
 			label = "lswvl:red:hdderr1";
-			gpios = <&gpio0 35 GPIO_ACTIVE_LOW>;
+			gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
 		};
 	};
 
@@ -233,7 +234,7 @@
 				3250 1
 				5000 0>;
 
-		alarm-gpios = <&gpio0 43 GPIO_ACTIVE_HIGH>;
+		alarm-gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>;
 	};
 
 	restart_poweroff {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/arm/boot/dts/kirkwood-lswxl.dts linux-libre-4.4.223-gnu/arch/arm/boot/dts/kirkwood-lswxl.dts
--- linux-libre-4.4.222-gnu/arch/arm/boot/dts/kirkwood-lswxl.dts	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/arm/boot/dts/kirkwood-lswxl.dts	2020-05-10 04:26:37.000000000 -0400
@@ -1,7 +1,8 @@
 /*
  * Device Tree file for Buffalo Linkstation LS-WXL/WSXL
  *
- * Copyright (C) 2015, rogershimizu@gmail.com
+ * Copyright (C) 2015, 2016
+ * Roger Shimizu <rogershimizu@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -156,21 +157,21 @@
 		button@1 {
 			label = "Function Button";
 			linux,code = <KEY_OPTION>;
-			gpios = <&gpio1 41 GPIO_ACTIVE_LOW>;
+			gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
 		};
 
 		button@2 {
 			label = "Power-on Switch";
 			linux,code = <KEY_RESERVED>;
 			linux,input-type = <5>;
-			gpios = <&gpio1 42 GPIO_ACTIVE_LOW>;
+			gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
 		};
 
 		button@3 {
 			label = "Power-auto Switch";
 			linux,code = <KEY_ESC>;
 			linux,input-type = <5>;
-			gpios = <&gpio1 43 GPIO_ACTIVE_LOW>;
+			gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
 		};
 	};
 
@@ -185,12 +186,12 @@
 
 		led@1 {
 			label = "lswxl:blue:func";
-			gpios = <&gpio1 36 GPIO_ACTIVE_LOW>;
+			gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
 		};
 
 		led@2 {
 			label = "lswxl:red:alarm";
-			gpios = <&gpio1 49 GPIO_ACTIVE_LOW>;
+			gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
 		};
 
 		led@3 {
@@ -200,23 +201,23 @@
 
 		led@4 {
 			label = "lswxl:blue:power";
-			gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
+			gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+			default-state = "keep";
 		};
 
 		led@5 {
 			label = "lswxl:red:func";
-			gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
-			default-state = "keep";
+			gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
 		};
 
 		led@6 {
 			label = "lswxl:red:hdderr0";
-			gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+			gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>;
 		};
 
 		led@7 {
 			label = "lswxl:red:hdderr1";
-			gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
+			gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>;
 		};
 	};
 
@@ -225,15 +226,15 @@
 		pinctrl-0 = <&pmx_fan_low &pmx_fan_high &pmx_fan_lock>;
 		pinctrl-names = "default";
 
-		gpios = <&gpio0 47 GPIO_ACTIVE_LOW
-			 &gpio0 48 GPIO_ACTIVE_LOW>;
+		gpios = <&gpio1 16 GPIO_ACTIVE_LOW
+			 &gpio1 15 GPIO_ACTIVE_LOW>;
 
 		gpio-fan,speed-map = <0 3
 				1500 2
 				3250 1
 				5000 0>;
 
-		alarm-gpios = <&gpio1 49 GPIO_ACTIVE_HIGH>;
+		alarm-gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
 	};
 
 	restart_poweroff {
@@ -256,7 +257,7 @@
 			enable-active-high;
 			regulator-always-on;
 			regulator-boot-on;
-			gpio = <&gpio0 37 GPIO_ACTIVE_HIGH>;
+			gpio = <&gpio1 5 GPIO_ACTIVE_HIGH>;
 		};
 		hdd_power0: regulator@2 {
 			compatible = "regulator-fixed";
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/arm/boot/dts/Makefile linux-libre-4.4.223-gnu/arch/arm/boot/dts/Makefile
--- linux-libre-4.4.222-gnu/arch/arm/boot/dts/Makefile	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/arm/boot/dts/Makefile	2020-05-10 04:26:37.000000000 -0400
@@ -166,6 +166,7 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += \
 	kirkwood-ds109.dtb \
 	kirkwood-ds110jv10.dtb \
 	kirkwood-ds111.dtb \
+	kirkwood-ds112.dtb \
 	kirkwood-ds209.dtb \
 	kirkwood-ds210.dtb \
 	kirkwood-ds212.dtb \
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts linux-libre-4.4.223-gnu/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts
--- linux-libre-4.4.222-gnu/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts	2020-05-10 04:26:37.000000000 -0400
@@ -1,7 +1,8 @@
 /*
  * Device Tree file for Buffalo Linkstation LS-WTGL
  *
- * Copyright (C) 2015, Roger Shimizu <rogershimizu@gmail.com>
+ * Copyright (C) 2015, 2016
+ * Roger Shimizu <rogershimizu@gmail.com>
  *
  * This file is dual-licensed: you can use it either under the terms
  * of the GPL or the X11 license, at your option. Note that this dual
@@ -69,8 +70,6 @@
 
 		internal-regs {
 			pinctrl: pinctrl@10000 {
-				pinctrl-0 = <&pmx_usb_power &pmx_power_hdd
-					&pmx_fan_low &pmx_fan_high &pmx_fan_lock>;
 				pinctrl-names = "default";
 
 				pmx_led_power: pmx-leds {
@@ -162,6 +161,7 @@
 		led@1 {
 			label = "lswtgl:blue:power";
 			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			default-state = "keep";
 		};
 
 		led@2 {
@@ -188,7 +188,7 @@
 				3250 1
 				5000 0>;
 
-		alarm-gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>;
+		alarm-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
 	};
 
 	restart_poweroff {
@@ -227,6 +227,37 @@
 		};
 	};
 };
+
+&devbus_bootcs {
+	status = "okay";
+	devbus,keep-config;
+
+	flash@0 {
+		compatible = "jedec-flash";
+		reg = <0 0x40000>;
+		bank-width = <1>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			header@0 {
+				reg = <0 0x30000>;
+				read-only;
+			};
+
+			uboot@30000 {
+				reg = <0x30000 0xF000>;
+				read-only;
+			};
+
+			uboot_env@3F000 {
+				reg = <0x3F000 0x1000>;
+			};
+		};
+	};
+};
 
 &mdio {
 	status = "okay";
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/arm/boot/dts/r8a7740-armadillo800eva.dts linux-libre-4.4.223-gnu/arch/arm/boot/dts/r8a7740-armadillo800eva.dts
--- linux-libre-4.4.222-gnu/arch/arm/boot/dts/r8a7740-armadillo800eva.dts	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/arm/boot/dts/r8a7740-armadillo800eva.dts	2020-05-10 04:26:37.000000000 -0400
@@ -180,7 +180,7 @@
 };
 
 &extal1_clk {
-	clock-frequency = <25000000>;
+	clock-frequency = <24000000>;
 };
 &extal2_clk {
 	clock-frequency = <48000000>;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/arm/mach-imx/Kconfig linux-libre-4.4.223-gnu/arch/arm/mach-imx/Kconfig
--- linux-libre-4.4.222-gnu/arch/arm/mach-imx/Kconfig	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/arm/mach-imx/Kconfig	2020-05-10 04:26:37.000000000 -0400
@@ -562,6 +562,7 @@ config SOC_IMX7D
 	select ARM_GIC
 	select HAVE_IMX_ANATOP
 	select HAVE_IMX_MMDC
+	select HAVE_IMX_SRC
 	help
 		This enables support for Freescale i.MX7 Dual processor.
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/arm/mach-omap2/omap_hwmod.c linux-libre-4.4.223-gnu/arch/arm/mach-omap2/omap_hwmod.c
--- linux-libre-4.4.222-gnu/arch/arm/mach-omap2/omap_hwmod.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/arm/mach-omap2/omap_hwmod.c	2020-05-10 04:26:37.000000000 -0400
@@ -2207,15 +2207,15 @@ static int _idle(struct omap_hwmod *oh)
 
 	pr_debug("omap_hwmod: %s: idling\n", oh->name);
 
+	if (_are_all_hardreset_lines_asserted(oh))
+		return 0;
+
 	if (oh->_state != _HWMOD_STATE_ENABLED) {
 		WARN(1, "omap_hwmod: %s: idle state can only be entered from enabled state\n",
 			oh->name);
 		return -EINVAL;
 	}
 
-	if (_are_all_hardreset_lines_asserted(oh))
-		return 0;
-
 	if (oh->class->sysc)
 		_idle_sysc(oh);
 	_del_initiator_dep(oh, mpu_oh);
@@ -2262,6 +2262,9 @@ static int _shutdown(struct omap_hwmod *
 	int ret, i;
 	u8 prev_state;
 
+	if (_are_all_hardreset_lines_asserted(oh))
+		return 0;
+
 	if (oh->_state != _HWMOD_STATE_IDLE &&
 	    oh->_state != _HWMOD_STATE_ENABLED) {
 		WARN(1, "omap_hwmod: %s: disabled state can only be entered from idle, or enabled state\n",
@@ -2269,9 +2272,6 @@ static int _shutdown(struct omap_hwmod *
 		return -EINVAL;
 	}
 
-	if (_are_all_hardreset_lines_asserted(oh))
-		return 0;
-
 	pr_debug("omap_hwmod: %s: disabling\n", oh->name);
 
 	if (oh->class->pre_shutdown) {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/arm64/net/bpf_jit_comp.c linux-libre-4.4.223-gnu/arch/arm64/net/bpf_jit_comp.c
--- linux-libre-4.4.222-gnu/arch/arm64/net/bpf_jit_comp.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/arm64/net/bpf_jit_comp.c	2020-05-10 04:26:37.000000000 -0400
@@ -482,6 +482,7 @@ emit_cond_jmp:
 		case BPF_JGE:
 			jmp_cond = A64_COND_CS;
 			break;
+		case BPF_JSET:
 		case BPF_JNE:
 			jmp_cond = A64_COND_NE;
 			break;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/boot/dts/brcm/bcm7435.dtsi linux-libre-4.4.223-gnu/arch/mips/boot/dts/brcm/bcm7435.dtsi
--- linux-libre-4.4.222-gnu/arch/mips/boot/dts/brcm/bcm7435.dtsi	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/boot/dts/brcm/bcm7435.dtsi	2020-05-10 04:26:37.000000000 -0400
@@ -7,7 +7,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 
-		mips-hpt-frequency = <163125000>;
+		mips-hpt-frequency = <175625000>;
 
 		cpu@0 {
 			compatible = "brcm,bmips5200";
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/cavium-octeon/octeon-irq.c linux-libre-4.4.223-gnu/arch/mips/cavium-octeon/octeon-irq.c
--- linux-libre-4.4.222-gnu/arch/mips/cavium-octeon/octeon-irq.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/cavium-octeon/octeon-irq.c	2020-05-10 04:26:37.000000000 -0400
@@ -1220,7 +1220,7 @@ static int octeon_irq_gpio_map(struct ir
 
 	line = (hw + gpiod->base_hwirq) >> 6;
 	bit = (hw + gpiod->base_hwirq) & 63;
-	if (line > ARRAY_SIZE(octeon_irq_ciu_to_irq) ||
+	if (line >= ARRAY_SIZE(octeon_irq_ciu_to_irq) ||
 		octeon_irq_ciu_to_irq[line][bit] != 0)
 		return -EINVAL;
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/cavium-octeon/setup.c linux-libre-4.4.223-gnu/arch/mips/cavium-octeon/setup.c
--- linux-libre-4.4.222-gnu/arch/mips/cavium-octeon/setup.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/cavium-octeon/setup.c	2020-05-10 04:26:37.000000000 -0400
@@ -251,6 +251,17 @@ static void octeon_crash_shutdown(struct
 	default_machine_crash_shutdown(regs);
 }
 
+#ifdef CONFIG_SMP
+void octeon_crash_smp_send_stop(void)
+{
+	int cpu;
+
+	/* disable watchdogs */
+	for_each_online_cpu(cpu)
+		cvmx_write_csr(CVMX_CIU_WDOGX(cpu_logical_map(cpu)), 0);
+}
+#endif
+
 #endif /* CONFIG_KEXEC */
 
 #ifdef CONFIG_CAVIUM_RESERVE32
@@ -864,6 +875,9 @@ void __init prom_init(void)
 	_machine_kexec_shutdown = octeon_shutdown;
 	_machine_crash_shutdown = octeon_crash_shutdown;
 	_machine_kexec_prepare = octeon_kexec_prepare;
+#ifdef CONFIG_SMP
+	_crash_smp_send_stop = octeon_crash_smp_send_stop;
+#endif
 #endif
 
 	octeon_user_io_init();
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/cavium-octeon/smp.c linux-libre-4.4.223-gnu/arch/mips/cavium-octeon/smp.c
--- linux-libre-4.4.222-gnu/arch/mips/cavium-octeon/smp.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/cavium-octeon/smp.c	2020-05-10 04:26:37.000000000 -0400
@@ -239,6 +239,7 @@ static int octeon_cpu_disable(void)
 		return -ENOTSUPP;
 
 	set_cpu_online(cpu, false);
+	calculate_cpu_foreign_map();
 	cpumask_clear_cpu(cpu, &cpu_callin_map);
 	octeon_fixup_irqs();
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/include/asm/elf.h linux-libre-4.4.223-gnu/arch/mips/include/asm/elf.h
--- linux-libre-4.4.222-gnu/arch/mips/include/asm/elf.h	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/include/asm/elf.h	2020-05-10 04:26:37.000000000 -0400
@@ -420,6 +420,7 @@ extern const char *__elf_platform;
 #define ELF_ET_DYN_BASE		(TASK_SIZE / 3 * 2)
 #endif
 
+/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
 #define ARCH_DLINFO							\
 do {									\
 	NEW_AUX_ENT(AT_SYSINFO_EHDR,					\
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/include/asm/kexec.h linux-libre-4.4.223-gnu/arch/mips/include/asm/kexec.h
--- linux-libre-4.4.222-gnu/arch/mips/include/asm/kexec.h	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/include/asm/kexec.h	2020-05-10 04:26:37.000000000 -0400
@@ -45,6 +45,7 @@ extern const unsigned char kexec_smp_wai
 extern unsigned long secondary_kexec_args[4];
 extern void (*relocated_kexec_smp_wait) (void *);
 extern atomic_t kexec_ready_to_reboot;
+extern void (*_crash_smp_send_stop)(void);
 #endif
 #endif
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/include/asm/r4kcache.h linux-libre-4.4.223-gnu/arch/mips/include/asm/r4kcache.h
--- linux-libre-4.4.222-gnu/arch/mips/include/asm/r4kcache.h	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/include/asm/r4kcache.h	2020-05-10 04:26:37.000000000 -0400
@@ -210,7 +210,11 @@ static inline void protected_writeback_d
 
 static inline void protected_writeback_scache_line(unsigned long addr)
 {
+#ifdef CONFIG_EVA
+	protected_cachee_op(Hit_Writeback_Inv_SD, addr);
+#else
 	protected_cache_op(Hit_Writeback_Inv_SD, addr);
+#endif
 }
 
 /*
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/include/asm/smp.h linux-libre-4.4.223-gnu/arch/mips/include/asm/smp.h
--- linux-libre-4.4.222-gnu/arch/mips/include/asm/smp.h	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/include/asm/smp.h	2020-05-10 04:26:37.000000000 -0400
@@ -63,6 +63,8 @@ extern cpumask_t cpu_coherent_mask;
 
 extern void asmlinkage smp_bootstrap(void);
 
+extern void calculate_cpu_foreign_map(void);
+
 /*
  * this function sends a 'reschedule' IPI to another CPU.
  * it goes straight through and wastes no time serializing
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/include/uapi/asm/auxvec.h linux-libre-4.4.223-gnu/arch/mips/include/uapi/asm/auxvec.h
--- linux-libre-4.4.222-gnu/arch/mips/include/uapi/asm/auxvec.h	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/include/uapi/asm/auxvec.h	2020-05-10 04:26:37.000000000 -0400
@@ -14,4 +14,6 @@
 /* Location of VDSO image. */
 #define AT_SYSINFO_EHDR		33
 
+#define AT_VECTOR_SIZE_ARCH 1 /* entries in ARCH_DLINFO */
+
 #endif /* __ASM_AUXVEC_H */
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/kernel/bmips_vec.S linux-libre-4.4.223-gnu/arch/mips/kernel/bmips_vec.S
--- linux-libre-4.4.222-gnu/arch/mips/kernel/bmips_vec.S	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/kernel/bmips_vec.S	2020-05-10 04:26:37.000000000 -0400
@@ -93,7 +93,8 @@ NESTED(bmips_reset_nmi_vec, PT_SIZE, sp)
 #if defined(CONFIG_CPU_BMIPS5000)
 	mfc0	k0, CP0_PRID
 	li	k1, PRID_IMP_BMIPS5000
-	andi	k0, 0xff00
+	/* mask with PRID_IMP_BMIPS5000 to cover both variants */
+	andi	k0, PRID_IMP_BMIPS5000
 	bne	k0, k1, 1f
 
 	/* if we're not on core 0, this must be the SMP boot signal */
@@ -166,10 +167,12 @@ bmips_smp_entry:
 2:
 #endif /* CONFIG_CPU_BMIPS4350 || CONFIG_CPU_BMIPS4380 */
 #if defined(CONFIG_CPU_BMIPS5000)
-	/* set exception vector base */
+	/* mask with PRID_IMP_BMIPS5000 to cover both variants */
 	li	k1, PRID_IMP_BMIPS5000
+	andi	k0, PRID_IMP_BMIPS5000
 	bne	k0, k1, 3f
 
+	/* set exception vector base */
 	la	k0, ebase
 	lw	k0, 0(k0)
 	mtc0	k0, $15, 1
@@ -263,6 +266,8 @@ LEAF(bmips_enable_xks01)
 #endif /* CONFIG_CPU_BMIPS4380 */
 #if defined(CONFIG_CPU_BMIPS5000)
 	li	t1, PRID_IMP_BMIPS5000
+	/* mask with PRID_IMP_BMIPS5000 to cover both variants */
+	andi	t2, PRID_IMP_BMIPS5000
 	bne	t2, t1, 2f
 
 	mfc0	t0, $22, 5
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/kernel/branch.c linux-libre-4.4.223-gnu/arch/mips/kernel/branch.c
--- linux-libre-4.4.222-gnu/arch/mips/kernel/branch.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/kernel/branch.c	2020-05-10 04:26:37.000000000 -0400
@@ -685,21 +685,9 @@ int __compute_return_epc_for_insn(struct
 			}
 			lose_fpu(1);    /* Save FPU state for the emulator. */
 			reg = insn.i_format.rt;
-			bit = 0;
-			switch (insn.i_format.rs) {
-			case bc1eqz_op:
-				/* Test bit 0 */
-				if (get_fpr32(&current->thread.fpu.fpr[reg], 0)
-				    & 0x1)
-					bit = 1;
-				break;
-			case bc1nez_op:
-				/* Test bit 0 */
-				if (!(get_fpr32(&current->thread.fpu.fpr[reg], 0)
-				      & 0x1))
-					bit = 1;
-				break;
-			}
+			bit = get_fpr32(&current->thread.fpu.fpr[reg], 0) & 0x1;
+			if (insn.i_format.rs == bc1eqz_op)
+				bit = !bit;
 			own_fpu(1);
 			if (bit)
 				epc = epc + 4 +
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/kernel/cps-vec.S linux-libre-4.4.223-gnu/arch/mips/kernel/cps-vec.S
--- linux-libre-4.4.222-gnu/arch/mips/kernel/cps-vec.S	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/kernel/cps-vec.S	2020-05-10 04:26:37.000000000 -0400
@@ -245,7 +245,6 @@ LEAF(excep_intex)
 
 .org 0x480
 LEAF(excep_ejtag)
-	DUMP_EXCEP("EJTAG")
 	PTR_LA	k0, ejtag_debug_handler
 	jr	k0
 	 nop
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/kernel/cpu-probe.c linux-libre-4.4.223-gnu/arch/mips/kernel/cpu-probe.c
--- linux-libre-4.4.222-gnu/arch/mips/kernel/cpu-probe.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/kernel/cpu-probe.c	2020-05-10 04:26:37.000000000 -0400
@@ -1284,7 +1284,10 @@ static inline void cpu_probe_broadcom(st
 	case PRID_IMP_BMIPS5000:
 	case PRID_IMP_BMIPS5200:
 		c->cputype = CPU_BMIPS5000;
-		__cpu_name[cpu] = "Broadcom BMIPS5000";
+		if ((c->processor_id & PRID_IMP_MASK) == PRID_IMP_BMIPS5200)
+			__cpu_name[cpu] = "Broadcom BMIPS5200";
+		else
+			__cpu_name[cpu] = "Broadcom BMIPS5000";
 		set_elf_platform(cpu, "bmips5000");
 		c->options |= MIPS_CPU_ULRI;
 		break;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/kernel/crash.c linux-libre-4.4.223-gnu/arch/mips/kernel/crash.c
--- linux-libre-4.4.222-gnu/arch/mips/kernel/crash.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/kernel/crash.c	2020-05-10 04:26:37.000000000 -0400
@@ -50,9 +50,14 @@ static void crash_shutdown_secondary(voi
 
 static void crash_kexec_prepare_cpus(void)
 {
+	static int cpus_stopped;
 	unsigned int msecs;
+	unsigned int ncpus;
 
-	unsigned int ncpus = num_online_cpus() - 1;/* Excluding the panic cpu */
+	if (cpus_stopped)
+		return;
+
+	ncpus = num_online_cpus() - 1;/* Excluding the panic cpu */
 
 	dump_send_ipi(crash_shutdown_secondary);
 	smp_wmb();
@@ -67,6 +72,17 @@ static void crash_kexec_prepare_cpus(voi
 		cpu_relax();
 		mdelay(1);
 	}
+
+	cpus_stopped = 1;
+}
+
+/* Override the weak function in kernel/panic.c */
+void crash_smp_send_stop(void)
+{
+	if (_crash_smp_send_stop)
+		_crash_smp_send_stop();
+
+	crash_kexec_prepare_cpus();
 }
 
 #else /* !defined(CONFIG_SMP)  */
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/kernel/machine_kexec.c linux-libre-4.4.223-gnu/arch/mips/kernel/machine_kexec.c
--- linux-libre-4.4.222-gnu/arch/mips/kernel/machine_kexec.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/kernel/machine_kexec.c	2020-05-10 04:26:37.000000000 -0400
@@ -25,6 +25,7 @@ void (*_machine_crash_shutdown)(struct p
 #ifdef CONFIG_SMP
 void (*relocated_kexec_smp_wait) (void *);
 atomic_t kexec_ready_to_reboot = ATOMIC_INIT(0);
+void (*_crash_smp_send_stop)(void) = NULL;
 #endif
 
 int
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/kernel/perf_event_mipsxx.c linux-libre-4.4.223-gnu/arch/mips/kernel/perf_event_mipsxx.c
--- linux-libre-4.4.222-gnu/arch/mips/kernel/perf_event_mipsxx.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/kernel/perf_event_mipsxx.c	2020-05-10 04:26:37.000000000 -0400
@@ -825,6 +825,16 @@ static const struct mips_perf_event mips
 	[PERF_COUNT_HW_BRANCH_MISSES] = { 0x27, CNTR_ODD, T },
 };
 
+static const struct mips_perf_event i6400_event_map[PERF_COUNT_HW_MAX] = {
+	[PERF_COUNT_HW_CPU_CYCLES]          = { 0x00, CNTR_EVEN | CNTR_ODD },
+	[PERF_COUNT_HW_INSTRUCTIONS]        = { 0x01, CNTR_EVEN | CNTR_ODD },
+	/* These only count dcache, not icache */
+	[PERF_COUNT_HW_CACHE_REFERENCES]    = { 0x45, CNTR_EVEN | CNTR_ODD },
+	[PERF_COUNT_HW_CACHE_MISSES]        = { 0x48, CNTR_EVEN | CNTR_ODD },
+	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 0x15, CNTR_EVEN | CNTR_ODD },
+	[PERF_COUNT_HW_BRANCH_MISSES]       = { 0x16, CNTR_EVEN | CNTR_ODD },
+};
+
 static const struct mips_perf_event loongson3_event_map[PERF_COUNT_HW_MAX] = {
 	[PERF_COUNT_HW_CPU_CYCLES] = { 0x00, CNTR_EVEN },
 	[PERF_COUNT_HW_INSTRUCTIONS] = { 0x00, CNTR_ODD },
@@ -1015,6 +1025,46 @@ static const struct mips_perf_event mips
 },
 };
 
+static const struct mips_perf_event i6400_cache_map
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+[C(L1D)] = {
+	[C(OP_READ)] = {
+		[C(RESULT_ACCESS)]	= { 0x46, CNTR_EVEN | CNTR_ODD },
+		[C(RESULT_MISS)]	= { 0x49, CNTR_EVEN | CNTR_ODD },
+	},
+	[C(OP_WRITE)] = {
+		[C(RESULT_ACCESS)]	= { 0x47, CNTR_EVEN | CNTR_ODD },
+		[C(RESULT_MISS)]	= { 0x4a, CNTR_EVEN | CNTR_ODD },
+	},
+},
+[C(L1I)] = {
+	[C(OP_READ)] = {
+		[C(RESULT_ACCESS)]	= { 0x84, CNTR_EVEN | CNTR_ODD },
+		[C(RESULT_MISS)]	= { 0x85, CNTR_EVEN | CNTR_ODD },
+	},
+},
+[C(DTLB)] = {
+	/* Can't distinguish read & write */
+	[C(OP_READ)] = {
+		[C(RESULT_ACCESS)]	= { 0x40, CNTR_EVEN | CNTR_ODD },
+		[C(RESULT_MISS)]	= { 0x41, CNTR_EVEN | CNTR_ODD },
+	},
+	[C(OP_WRITE)] = {
+		[C(RESULT_ACCESS)]	= { 0x40, CNTR_EVEN | CNTR_ODD },
+		[C(RESULT_MISS)]	= { 0x41, CNTR_EVEN | CNTR_ODD },
+	},
+},
+[C(BPU)] = {
+	/* Conditional branches / mispredicted */
+	[C(OP_READ)] = {
+		[C(RESULT_ACCESS)]	= { 0x15, CNTR_EVEN | CNTR_ODD },
+		[C(RESULT_MISS)]	= { 0x16, CNTR_EVEN | CNTR_ODD },
+	},
+},
+};
+
 static const struct mips_perf_event loongson3_cache_map
 				[PERF_COUNT_HW_CACHE_MAX]
 				[PERF_COUNT_HW_CACHE_OP_MAX]
@@ -1556,7 +1606,6 @@ static const struct mips_perf_event *mip
 #endif
 		break;
 	case CPU_P5600:
-	case CPU_I6400:
 		/* 8-bit event numbers */
 		raw_id = config & 0x1ff;
 		base_id = raw_id & 0xff;
@@ -1569,6 +1618,11 @@ static const struct mips_perf_event *mip
 		raw_event.range = P;
 #endif
 		break;
+	case CPU_I6400:
+		/* 8-bit event numbers */
+		base_id = config & 0xff;
+		raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
+		break;
 	case CPU_1004K:
 		if (IS_BOTH_COUNTERS_1004K_EVENT(base_id))
 			raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
@@ -1720,8 +1774,8 @@ init_hw_perf_events(void)
 		break;
 	case CPU_I6400:
 		mipspmu.name = "mips/I6400";
-		mipspmu.general_event_map = &mipsxxcore_event_map2;
-		mipspmu.cache_event_map = &mipsxxcore_cache_map2;
+		mipspmu.general_event_map = &i6400_event_map;
+		mipspmu.cache_event_map = &i6400_cache_map;
 		break;
 	case CPU_1004K:
 		mipspmu.name = "mips/1004K";
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/kernel/ptrace.c linux-libre-4.4.223-gnu/arch/mips/kernel/ptrace.c
--- linux-libre-4.4.222-gnu/arch/mips/kernel/ptrace.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/kernel/ptrace.c	2020-05-10 04:26:37.000000000 -0400
@@ -670,9 +670,6 @@ static const struct pt_regs_offset regof
 	REG_OFFSET_NAME(c0_badvaddr, cp0_badvaddr),
 	REG_OFFSET_NAME(c0_cause, cp0_cause),
 	REG_OFFSET_NAME(c0_epc, cp0_epc),
-#ifdef CONFIG_MIPS_MT_SMTC
-	REG_OFFSET_NAME(c0_tcstatus, cp0_tcstatus),
-#endif
 #ifdef CONFIG_CPU_CAVIUM_OCTEON
 	REG_OFFSET_NAME(mpl0, mpl[0]),
 	REG_OFFSET_NAME(mpl1, mpl[1]),
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/kernel/scall32-o32.S linux-libre-4.4.223-gnu/arch/mips/kernel/scall32-o32.S
--- linux-libre-4.4.222-gnu/arch/mips/kernel/scall32-o32.S	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/kernel/scall32-o32.S	2020-05-10 04:26:37.000000000 -0400
@@ -35,7 +35,6 @@ NESTED(handle_sys, PT_SIZE, sp)
 
 	lw	t1, PT_EPC(sp)		# skip syscall on return
 
-	subu	v0, v0, __NR_O32_Linux	# check syscall number
 	addiu	t1, 4			# skip to next instruction
 	sw	t1, PT_EPC(sp)
 
@@ -89,6 +88,7 @@ loads_done:
 	and	t0, t1
 	bnez	t0, syscall_trace_entry # -> yes
 syscall_common:
+	subu	v0, v0, __NR_O32_Linux	# check syscall number
 	sltiu	t0, v0, __NR_O32_Linux_syscalls + 1
 	beqz	t0, illegal_syscall
 
@@ -118,24 +118,23 @@ o32_syscall_exit:
 
 syscall_trace_entry:
 	SAVE_STATIC
-	move	s0, v0
 	move	a0, sp
 
 	/*
 	 * syscall number is in v0 unless we called syscall(__NR_###)
 	 * where the real syscall number is in a0
 	 */
-	addiu	a1, v0,  __NR_O32_Linux
-	bnez	v0, 1f /* __NR_syscall at offset 0 */
+	move	a1, v0
+	subu	t2, v0,  __NR_O32_Linux
+	bnez	t2, 1f /* __NR_syscall at offset 0 */
 	lw	a1, PT_R4(sp)
 
 1:	jal	syscall_trace_enter
 
 	bltz	v0, 1f			# seccomp failed? Skip syscall
 
-	move	v0, s0			# restore syscall
-
 	RESTORE_STATIC
+	lw	v0, PT_R2(sp)		# Restore syscall (maybe modified)
 	lw	a0, PT_R4(sp)		# Restore argument registers
 	lw	a1, PT_R5(sp)
 	lw	a2, PT_R6(sp)
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/kernel/scall64-64.S linux-libre-4.4.223-gnu/arch/mips/kernel/scall64-64.S
--- linux-libre-4.4.222-gnu/arch/mips/kernel/scall64-64.S	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/kernel/scall64-64.S	2020-05-10 04:26:37.000000000 -0400
@@ -82,15 +82,14 @@ n64_syscall_exit:
 
 syscall_trace_entry:
 	SAVE_STATIC
-	move	s0, v0
 	move	a0, sp
 	move	a1, v0
 	jal	syscall_trace_enter
 
 	bltz	v0, 1f			# seccomp failed? Skip syscall
 
-	move	v0, s0
 	RESTORE_STATIC
+	ld	v0, PT_R2(sp)		# Restore syscall (maybe modified)
 	ld	a0, PT_R4(sp)		# Restore argument registers
 	ld	a1, PT_R5(sp)
 	ld	a2, PT_R6(sp)
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/kernel/scall64-n32.S linux-libre-4.4.223-gnu/arch/mips/kernel/scall64-n32.S
--- linux-libre-4.4.222-gnu/arch/mips/kernel/scall64-n32.S	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/kernel/scall64-n32.S	2020-05-10 04:26:37.000000000 -0400
@@ -42,9 +42,6 @@ NESTED(handle_sysn32, PT_SIZE, sp)
 #endif
 	beqz	t0, not_n32_scall
 
-	dsll	t0, v0, 3		# offset into table
-	ld	t2, (sysn32_call_table - (__NR_N32_Linux * 8))(t0)
-
 	sd	a3, PT_R26(sp)		# save a3 for syscall restarting
 
 	li	t1, _TIF_WORK_SYSCALL_ENTRY
@@ -53,6 +50,9 @@ NESTED(handle_sysn32, PT_SIZE, sp)
 	bnez	t0, n32_syscall_trace_entry
 
 syscall_common:
+	dsll	t0, v0, 3		# offset into table
+	ld	t2, (sysn32_call_table - (__NR_N32_Linux * 8))(t0)
+
 	jalr	t2			# Do The Real Thing (TM)
 
 	li	t0, -EMAXERRNO - 1	# error?
@@ -71,21 +71,25 @@ syscall_common:
 
 n32_syscall_trace_entry:
 	SAVE_STATIC
-	move	s0, t2
 	move	a0, sp
 	move	a1, v0
 	jal	syscall_trace_enter
 
 	bltz	v0, 1f			# seccomp failed? Skip syscall
 
-	move	t2, s0
 	RESTORE_STATIC
+	ld	v0, PT_R2(sp)		# Restore syscall (maybe modified)
 	ld	a0, PT_R4(sp)		# Restore argument registers
 	ld	a1, PT_R5(sp)
 	ld	a2, PT_R6(sp)
 	ld	a3, PT_R7(sp)
 	ld	a4, PT_R8(sp)
 	ld	a5, PT_R9(sp)
+
+	dsubu	t2, v0, __NR_N32_Linux	# check (new) syscall number
+	sltiu   t0, t2, __NR_N32_Linux_syscalls + 1
+	beqz	t0, not_n32_scall
+
 	j	syscall_common
 
 1:	j	syscall_exit
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/kernel/scall64-o32.S linux-libre-4.4.223-gnu/arch/mips/kernel/scall64-o32.S
--- linux-libre-4.4.222-gnu/arch/mips/kernel/scall64-o32.S	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/kernel/scall64-o32.S	2020-05-10 04:26:37.000000000 -0400
@@ -52,9 +52,6 @@ NESTED(handle_sys, PT_SIZE, sp)
 	sll	a2, a2, 0
 	sll	a3, a3, 0
 
-	dsll	t0, v0, 3		# offset into table
-	ld	t2, (sys32_call_table - (__NR_O32_Linux * 8))(t0)
-
 	sd	a3, PT_R26(sp)		# save a3 for syscall restarting
 
 	/*
@@ -88,6 +85,9 @@ loads_done:
 	bnez	t0, trace_a_syscall
 
 syscall_common:
+	dsll	t0, v0, 3		# offset into table
+	ld	t2, (sys32_call_table - (__NR_O32_Linux * 8))(t0)
+
 	jalr	t2			# Do The Real Thing (TM)
 
 	li	t0, -EMAXERRNO - 1	# error?
@@ -112,7 +112,6 @@ trace_a_syscall:
 	sd	a6, PT_R10(sp)
 	sd	a7, PT_R11(sp)		# For indirect syscalls
 
-	move	s0, t2			# Save syscall pointer
 	move	a0, sp
 	/*
 	 * absolute syscall number is in v0 unless we called syscall(__NR_###)
@@ -133,8 +132,8 @@ trace_a_syscall:
 
 	bltz	v0, 1f			# seccomp failed? Skip syscall
 
-	move	t2, s0
 	RESTORE_STATIC
+	ld	v0, PT_R2(sp)		# Restore syscall (maybe modified)
 	ld	a0, PT_R4(sp)		# Restore argument registers
 	ld	a1, PT_R5(sp)
 	ld	a2, PT_R6(sp)
@@ -143,6 +142,11 @@ trace_a_syscall:
 	ld	a5, PT_R9(sp)
 	ld	a6, PT_R10(sp)
 	ld	a7, PT_R11(sp)		# For indirect syscalls
+
+	dsubu	t0, v0, __NR_O32_Linux	# check (new) syscall number
+	sltiu	t0, t0, __NR_O32_Linux_syscalls + 1
+	beqz	t0, not_o32_scall
+
 	j	syscall_common
 
 1:	j	syscall_exit
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/kernel/setup.c linux-libre-4.4.223-gnu/arch/mips/kernel/setup.c
--- linux-libre-4.4.222-gnu/arch/mips/kernel/setup.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/kernel/setup.c	2020-05-10 04:26:37.000000000 -0400
@@ -695,7 +695,7 @@ static void __init request_crashkernel(s
 
 #define USE_PROM_CMDLINE	IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER)
 #define USE_DTB_CMDLINE		IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB)
-#define EXTEND_WITH_PROM	IS_ENABLED(CONFIG_MIPS_CMDLINE_EXTEND)
+#define EXTEND_WITH_PROM	IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND)
 
 static void __init arch_mem_init(char **cmdline_p)
 {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/kernel/smp-bmips.c linux-libre-4.4.223-gnu/arch/mips/kernel/smp-bmips.c
--- linux-libre-4.4.222-gnu/arch/mips/kernel/smp-bmips.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/kernel/smp-bmips.c	2020-05-10 04:26:37.000000000 -0400
@@ -362,6 +362,7 @@ static int bmips_cpu_disable(void)
 	pr_info("SMP: CPU%d is offline\n", cpu);
 
 	set_cpu_online(cpu, false);
+	calculate_cpu_foreign_map();
 	cpumask_clear_cpu(cpu, &cpu_callin_map);
 	clear_c0_status(IE_IRQ5);
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/kernel/smp.c linux-libre-4.4.223-gnu/arch/mips/kernel/smp.c
--- linux-libre-4.4.222-gnu/arch/mips/kernel/smp.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/kernel/smp.c	2020-05-10 04:26:37.000000000 -0400
@@ -118,7 +118,7 @@ static inline void set_cpu_core_map(int
  * Calculate a new cpu_foreign_map mask whenever a
  * new cpu appears or disappears.
  */
-static inline void calculate_cpu_foreign_map(void)
+void calculate_cpu_foreign_map(void)
 {
 	int i, k, core_present;
 	cpumask_t temp_foreign_map;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/kernel/smp-cps.c linux-libre-4.4.223-gnu/arch/mips/kernel/smp-cps.c
--- linux-libre-4.4.222-gnu/arch/mips/kernel/smp-cps.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/kernel/smp-cps.c	2020-05-10 04:26:37.000000000 -0400
@@ -338,6 +338,7 @@ static int cps_cpu_disable(void)
 	atomic_sub(1 << cpu_vpe_id(&current_cpu_data), &core_cfg->vpe_mask);
 	smp_mb__after_atomic();
 	set_cpu_online(cpu, false);
+	calculate_cpu_foreign_map();
 	cpumask_clear_cpu(cpu, &cpu_callin_map);
 
 	return 0;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/kvm/dyntrans.c linux-libre-4.4.223-gnu/arch/mips/kvm/dyntrans.c
--- linux-libre-4.4.222-gnu/arch/mips/kvm/dyntrans.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/kvm/dyntrans.c	2020-05-10 04:26:37.000000000 -0400
@@ -82,7 +82,7 @@ int kvm_mips_trans_mfc0(uint32_t inst, u
 
 	if ((rd == MIPS_CP0_ERRCTL) && (sel == 0)) {
 		mfc0_inst = CLEAR_TEMPLATE;
-		mfc0_inst |= ((rt & 0x1f) << 16);
+		mfc0_inst |= ((rt & 0x1f) << 11);
 	} else {
 		mfc0_inst = LW_TEMPLATE;
 		mfc0_inst |= ((rt & 0x1f) << 16);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/loongson64/loongson-3/smp.c linux-libre-4.4.223-gnu/arch/mips/loongson64/loongson-3/smp.c
--- linux-libre-4.4.222-gnu/arch/mips/loongson64/loongson-3/smp.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/loongson64/loongson-3/smp.c	2020-05-10 04:26:37.000000000 -0400
@@ -417,6 +417,7 @@ static int loongson3_cpu_disable(void)
 		return -EBUSY;
 
 	set_cpu_online(cpu, false);
+	calculate_cpu_foreign_map();
 	cpumask_clear_cpu(cpu, &cpu_callin_map);
 	local_irq_save(flags);
 	fixup_irqs();
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/math-emu/cp1emu.c linux-libre-4.4.223-gnu/arch/mips/math-emu/cp1emu.c
--- linux-libre-4.4.222-gnu/arch/mips/math-emu/cp1emu.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/math-emu/cp1emu.c	2020-05-10 04:26:37.000000000 -0400
@@ -975,9 +975,10 @@ static int cop1Emulate(struct pt_regs *x
 		struct mm_decoded_insn dec_insn, void *__user *fault_addr)
 {
 	unsigned long contpc = xcp->cp0_epc + dec_insn.pc_inc;
-	unsigned int cond, cbit;
+	unsigned int cond, cbit, bit0;
 	mips_instruction ir;
 	int likely, pc_inc;
+	union fpureg *fpr;
 	u32 __user *wva;
 	u64 __user *dva;
 	u32 wval;
@@ -1189,14 +1190,14 @@ emul:
 				return SIGILL;
 
 			cond = likely = 0;
+			fpr = &current->thread.fpu.fpr[MIPSInst_RT(ir)];
+			bit0 = get_fpr32(fpr, 0) & 0x1;
 			switch (MIPSInst_RS(ir)) {
 			case bc1eqz_op:
-				if (get_fpr32(&current->thread.fpu.fpr[MIPSInst_RT(ir)], 0) & 0x1)
-				    cond = 1;
+				cond = bit0 == 0;
 				break;
 			case bc1nez_op:
-				if (!(get_fpr32(&current->thread.fpu.fpr[MIPSInst_RT(ir)], 0) & 0x1))
-				    cond = 1;
+				cond = bit0 != 0;
 				break;
 			}
 			goto branch_common;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/mm/c-r4k.c linux-libre-4.4.223-gnu/arch/mips/mm/c-r4k.c
--- linux-libre-4.4.222-gnu/arch/mips/mm/c-r4k.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/mm/c-r4k.c	2020-05-10 04:26:37.000000000 -0400
@@ -447,6 +447,11 @@ static inline void local_r4k___flush_cac
 		r4k_blast_scache();
 		break;
 
+	case CPU_BMIPS5000:
+		r4k_blast_scache();
+		__sync();
+		break;
+
 	default:
 		r4k_blast_dcache();
 		r4k_blast_icache();
@@ -1308,6 +1313,12 @@ static void probe_pcache(void)
 		c->icache.flags |= MIPS_CACHE_IC_F_DC;
 		break;
 
+	case CPU_BMIPS5000:
+		c->icache.flags |= MIPS_CACHE_IC_F_DC;
+		/* Cache aliases are handled in hardware; allow HIGHMEM */
+		c->dcache.flags &= ~MIPS_CACHE_ALIASES;
+		break;
+
 	case CPU_LOONGSON2:
 		/*
 		 * LOONGSON2 has 4 way icache, but when using indexed cache op,
@@ -1745,8 +1756,6 @@ void r4k_cache_init(void)
 		flush_icache_range = (void *)b5k_instruction_hazard;
 		local_flush_icache_range = (void *)b5k_instruction_hazard;
 
-		/* Cache aliases are handled in hardware; allow HIGHMEM */
-		current_cpu_data.dcache.flags &= ~MIPS_CACHE_ALIASES;
 
 		/* Optimization: an L2 flush implicitly flushes the L1 */
 		current_cpu_data.options |= MIPS_CPU_INCLUSIVE_CACHES;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/mm/sc-rm7k.c linux-libre-4.4.223-gnu/arch/mips/mm/sc-rm7k.c
--- linux-libre-4.4.222-gnu/arch/mips/mm/sc-rm7k.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/mm/sc-rm7k.c	2020-05-10 04:26:37.000000000 -0400
@@ -161,7 +161,7 @@ static void rm7k_tc_disable(void)
 	local_irq_save(flags);
 	blast_rm7k_tcache();
 	clear_c0_config(RM7K_CONF_TE);
-	local_irq_save(flags);
+	local_irq_restore(flags);
 }
 
 static void rm7k_sc_disable(void)
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/mm/tlbex.c linux-libre-4.4.223-gnu/arch/mips/mm/tlbex.c
--- linux-libre-4.4.222-gnu/arch/mips/mm/tlbex.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/mm/tlbex.c	2020-05-10 04:26:37.000000000 -0400
@@ -2329,9 +2329,7 @@ static void config_htw_params(void)
 	if (CONFIG_PGTABLE_LEVELS >= 3)
 		pwsize |= ilog2(PTRS_PER_PMD) << MIPS_PWSIZE_MDW_SHIFT;
 
-	/* If XPA has been enabled, PTEs are 64-bit in size. */
-	if (config_enabled(CONFIG_64BITS) || (read_c0_pagegrain() & PG_ELPA))
-		pwsize |= 1;
+	pwsize |= ilog2(sizeof(pte_t)/4) << MIPS_PWSIZE_PTEW_SHIFT;
 
 	write_c0_pwsize(pwsize);
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/mips/net/bpf_jit.c linux-libre-4.4.223-gnu/arch/mips/net/bpf_jit.c
--- linux-libre-4.4.222-gnu/arch/mips/net/bpf_jit.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/mips/net/bpf_jit.c	2020-05-10 04:26:37.000000000 -0400
@@ -1207,7 +1207,7 @@ void bpf_jit_compile(struct bpf_prog *fp
 
 	memset(&ctx, 0, sizeof(ctx));
 
-	ctx.offsets = kcalloc(fp->len, sizeof(*ctx.offsets), GFP_KERNEL);
+	ctx.offsets = kcalloc(fp->len + 1, sizeof(*ctx.offsets), GFP_KERNEL);
 	if (ctx.offsets == NULL)
 		return;
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/powerpc/kernel/mce.c linux-libre-4.4.223-gnu/arch/powerpc/kernel/mce.c
--- linux-libre-4.4.222-gnu/arch/powerpc/kernel/mce.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/powerpc/kernel/mce.c	2020-05-10 04:26:37.000000000 -0400
@@ -92,7 +92,8 @@ void save_mce_event(struct pt_regs *regs
 	mce->in_use = 1;
 
 	mce->initiator = MCE_INITIATOR_CPU;
-	if (handled)
+	/* Mark it recovered if we have handled it and MSR(RI=1). */
+	if (handled && (regs->msr & MSR_RI))
 		mce->disposition = MCE_DISPOSITION_RECOVERED;
 	else
 		mce->disposition = MCE_DISPOSITION_NOT_RECOVERED;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/powerpc/kernel/pci_of_scan.c linux-libre-4.4.223-gnu/arch/powerpc/kernel/pci_of_scan.c
--- linux-libre-4.4.222-gnu/arch/powerpc/kernel/pci_of_scan.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/powerpc/kernel/pci_of_scan.c	2020-05-10 04:26:37.000000000 -0400
@@ -82,10 +82,16 @@ static void of_pci_parse_addrs(struct de
 	const __be32 *addrs;
 	u32 i;
 	int proplen;
+	bool mark_unset = false;
 
 	addrs = of_get_property(node, "assigned-addresses", &proplen);
-	if (!addrs)
-		return;
+	if (!addrs || !proplen) {
+		addrs = of_get_property(node, "reg", &proplen);
+		if (!addrs || !proplen)
+			return;
+		mark_unset = true;
+	}
+
 	pr_debug("    parse addresses (%d bytes) @ %p\n", proplen, addrs);
 	for (; proplen >= 20; proplen -= 20, addrs += 5) {
 		flags = pci_parse_of_flags(of_read_number(addrs, 1), 0);
@@ -110,6 +116,8 @@ static void of_pci_parse_addrs(struct de
 			continue;
 		}
 		res->flags = flags;
+		if (mark_unset)
+			res->flags |= IORESOURCE_UNSET;
 		res->name = pci_name(dev);
 		region.start = base;
 		region.end = base + size - 1;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/powerpc/kernel/tm.S linux-libre-4.4.223-gnu/arch/powerpc/kernel/tm.S
--- linux-libre-4.4.222-gnu/arch/powerpc/kernel/tm.S	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/powerpc/kernel/tm.S	2020-05-10 04:26:37.000000000 -0400
@@ -352,8 +352,6 @@ _GLOBAL(__tm_recheckpoint)
 	 */
 	subi	r7, r7, STACK_FRAME_OVERHEAD
 
-	SET_SCRATCH0(r1)
-
 	mfmsr	r6
 	/* R4 = original MSR to indicate whether thread used FP/Vector etc. */
 
@@ -482,6 +480,7 @@ restore_gprs:
 	 * until we turn MSR RI back on.
 	 */
 
+	SET_SCRATCH0(r1)
 	ld	r5, -8(r1)
 	ld	r1, -16(r1)
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/powerpc/platforms/powernv/opal.c linux-libre-4.4.223-gnu/arch/powerpc/platforms/powernv/opal.c
--- linux-libre-4.4.222-gnu/arch/powerpc/platforms/powernv/opal.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/powerpc/platforms/powernv/opal.c	2020-05-10 04:26:37.000000000 -0400
@@ -401,6 +401,7 @@ static int opal_recover_mce(struct pt_re
 
 	if (!(regs->msr & MSR_RI)) {
 		/* If MSR_RI isn't set, we cannot recover */
+		pr_err("Machine check interrupt unrecoverable: MSR(RI=0)\n");
 		recovered = 0;
 	} else if (evt->disposition == MCE_DISPOSITION_RECOVERED) {
 		/* Platform corrected itself */
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/x86/kernel/apic/x2apic_uv_x.c linux-libre-4.4.223-gnu/arch/x86/kernel/apic/x2apic_uv_x.c
--- linux-libre-4.4.222-gnu/arch/x86/kernel/apic/x2apic_uv_x.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/x86/kernel/apic/x2apic_uv_x.c	2020-05-10 04:26:37.000000000 -0400
@@ -648,9 +648,9 @@ static __init void map_mmioh_high_uv3(in
 				l = li;
 			}
 			addr1 = (base << shift) +
-				f * (unsigned long)(1 << m_io);
+				f * (1ULL << m_io);
 			addr2 = (base << shift) +
-				(l + 1) * (unsigned long)(1 << m_io);
+				(l + 1) * (1ULL << m_io);
 			pr_info("UV: %s[%03d..%03d] NASID 0x%04x ADDR 0x%016lx - 0x%016lx\n",
 				id, fi, li, lnasid, addr1, addr2);
 			if (max_io < l)
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/x86/kernel/cpu/perf_event.c linux-libre-4.4.223-gnu/arch/x86/kernel/cpu/perf_event.c
--- linux-libre-4.4.222-gnu/arch/x86/kernel/cpu/perf_event.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/x86/kernel/cpu/perf_event.c	2020-05-10 04:26:37.000000000 -0400
@@ -1550,6 +1550,7 @@ static void __init filter_events(struct
 {
 	struct device_attribute *d;
 	struct perf_pmu_events_attr *pmu_attr;
+	int offset = 0;
 	int i, j;
 
 	for (i = 0; attrs[i]; i++) {
@@ -1558,7 +1559,7 @@ static void __init filter_events(struct
 		/* str trumps id */
 		if (pmu_attr->event_str)
 			continue;
-		if (x86_pmu.event_map(i))
+		if (x86_pmu.event_map(i + offset))
 			continue;
 
 		for (j = i; attrs[j]; j++)
@@ -1566,6 +1567,14 @@ static void __init filter_events(struct
 
 		/* Check the shifted attr. */
 		i--;
+
+		/*
+		 * event_map() is index based, the attrs array is organized
+		 * by increasing event index. If we shift the events, then
+		 * we need to compensate for the event_map(), otherwise
+		 * we are looking up the wrong event in the map
+		 */
+		offset++;
 	}
 }
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/arch/x86/kernel/process_64.c linux-libre-4.4.223-gnu/arch/x86/kernel/process_64.c
--- linux-libre-4.4.222-gnu/arch/x86/kernel/process_64.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/arch/x86/kernel/process_64.c	2020-05-10 04:26:37.000000000 -0400
@@ -128,7 +128,7 @@ void release_thread(struct task_struct *
 		if (dead_task->mm->context.ldt) {
 			pr_warn("WARNING: dead process %s still has LDT? <%p/%d>\n",
 				dead_task->comm,
-				dead_task->mm->context.ldt,
+				dead_task->mm->context.ldt->entries,
 				dead_task->mm->context.ldt->size);
 			BUG();
 		}
diff -druNp --no-dereference linux-libre-4.4.222-gnu/block/blk-mq.c linux-libre-4.4.223-gnu/block/blk-mq.c
--- linux-libre-4.4.222-gnu/block/blk-mq.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/block/blk-mq.c	2020-05-10 04:26:37.000000000 -0400
@@ -1491,7 +1491,7 @@ static struct blk_mq_tags *blk_mq_init_r
 		int to_do;
 		void *p;
 
-		while (left < order_to_size(this_order - 1) && this_order)
+		while (this_order && left < order_to_size(this_order - 1))
 			this_order--;
 
 		do {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/acpi/acpi_lpss.c linux-libre-4.4.223-gnu/drivers/acpi/acpi_lpss.c
--- linux-libre-4.4.222-gnu/drivers/acpi/acpi_lpss.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/acpi/acpi_lpss.c	2020-05-10 04:26:37.000000000 -0400
@@ -704,8 +704,13 @@ static int acpi_lpss_platform_notify(str
 	}
 
 	switch (action) {
-	case BUS_NOTIFY_ADD_DEVICE:
+	case BUS_NOTIFY_BOUND_DRIVER:
 		pdev->dev.pm_domain = &acpi_lpss_pm_domain;
+		break;
+	case BUS_NOTIFY_UNBOUND_DRIVER:
+		pdev->dev.pm_domain = NULL;
+		break;
+	case BUS_NOTIFY_ADD_DEVICE:
 		if (pdata->dev_desc->flags & LPSS_LTR)
 			return sysfs_create_group(&pdev->dev.kobj,
 						  &lpss_attr_group);
@@ -713,7 +718,6 @@ static int acpi_lpss_platform_notify(str
 	case BUS_NOTIFY_DEL_DEVICE:
 		if (pdata->dev_desc->flags & LPSS_LTR)
 			sysfs_remove_group(&pdev->dev.kobj, &lpss_attr_group);
-		pdev->dev.pm_domain = NULL;
 		break;
 	default:
 		break;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/ata/sata_dwc_460ex.c linux-libre-4.4.223-gnu/drivers/ata/sata_dwc_460ex.c
--- linux-libre-4.4.222-gnu/drivers/ata/sata_dwc_460ex.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/ata/sata_dwc_460ex.c	2020-05-10 04:26:37.000000000 -0400
@@ -924,15 +924,13 @@ static void sata_dwc_exec_command_by_tag
 					 struct ata_taskfile *tf,
 					 u8 tag, u32 cmd_issued)
 {
-	unsigned long flags;
 	struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap);
 
 	dev_dbg(ap->dev, "%s cmd(0x%02x): %s tag=%d\n", __func__, tf->command,
 		ata_get_cmd_descript(tf->command), tag);
 
-	spin_lock_irqsave(&ap->host->lock, flags);
 	hsdevp->cmd_issued[tag] = cmd_issued;
-	spin_unlock_irqrestore(&ap->host->lock, flags);
+
 	/*
 	 * Clear SError before executing a new command.
 	 * sata_dwc_scr_write and read can not be used here. Clearing the PM
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/base/firmware_class.c linux-libre-4.4.223-gnu/drivers/base/firmware_class.c
--- linux-libre-4.4.222-gnu/drivers/base/firmware_class.c	2020-05-05 15:12:56.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/base/firmware_class.c	2020-05-10 18:47:55.000000000 -0400
@@ -1119,15 +1119,17 @@ static int
 _request_firmware(const struct firmware **firmware_p, const char *name,
 		  struct device *device, unsigned int opt_flags)
 {
-	struct firmware *fw;
+	struct firmware *fw = NULL;
 	long timeout;
 	int ret;
 
 	if (!firmware_p)
 		return -EINVAL;
 
-	if (!name || name[0] == '\0')
-		return -EINVAL;
+	if (!name || name[0] == '\0') {
+		ret = -EINVAL;
+		goto out;
+	}
 
 	ret = _request_firmware_prepare(&fw, name, device);
 	if (ret <= 0) /* error or already assigned */
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/base/isa.c linux-libre-4.4.223-gnu/drivers/base/isa.c
--- linux-libre-4.4.222-gnu/drivers/base/isa.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/base/isa.c	2020-05-10 04:26:37.000000000 -0400
@@ -180,4 +180,4 @@ static int __init isa_bus_init(void)
 	return error;
 }
 
-device_initcall(isa_bus_init);
+postcore_initcall(isa_bus_init);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/bluetooth/btmrvl_sdio.c linux-libre-4.4.223-gnu/drivers/bluetooth/btmrvl_sdio.c
--- linux-libre-4.4.222-gnu/drivers/bluetooth/btmrvl_sdio.c	2020-05-05 15:40:53.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/bluetooth/btmrvl_sdio.c	2020-05-10 19:05:23.000000000 -0400
@@ -1112,7 +1112,8 @@ static int btmrvl_sdio_download_fw(struc
 	 */
 	if (btmrvl_sdio_verify_fw_download(card, pollnum)) {
 		BT_ERR("FW failed to be active in time!");
-		return -ETIMEDOUT;
+		ret = -ETIMEDOUT;
+		goto done;
 	}
 
 	sdio_release_host(card->func);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/char/hw_random/exynos-rng.c linux-libre-4.4.223-gnu/drivers/char/hw_random/exynos-rng.c
--- linux-libre-4.4.222-gnu/drivers/char/hw_random/exynos-rng.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/char/hw_random/exynos-rng.c	2020-05-10 04:26:37.000000000 -0400
@@ -155,6 +155,14 @@ static int exynos_rng_probe(struct platf
 	return ret;
 }
 
+static int exynos_rng_remove(struct platform_device *pdev)
+{
+	pm_runtime_dont_use_autosuspend(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+
+	return 0;
+}
+
 static int __maybe_unused exynos_rng_runtime_suspend(struct device *dev)
 {
 	struct platform_device *pdev = to_platform_device(dev);
@@ -212,6 +220,7 @@ static struct platform_driver exynos_rng
 		.of_match_table = exynos_rng_dt_match,
 	},
 	.probe		= exynos_rng_probe,
+	.remove		= exynos_rng_remove,
 };
 
 module_platform_driver(exynos_rng_driver);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/clk/clk-gpio.c linux-libre-4.4.223-gnu/drivers/clk/clk-gpio.c
--- linux-libre-4.4.222-gnu/drivers/clk/clk-gpio.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/clk/clk-gpio.c	2020-05-10 04:26:37.000000000 -0400
@@ -287,12 +287,14 @@ static void __init of_gpio_clk_setup(str
 	const char **parent_names;
 	int i, num_parents;
 
+	num_parents = of_clk_get_parent_count(node);
+	if (num_parents < 0)
+		return;
+
 	data = kzalloc(sizeof(*data), GFP_KERNEL);
 	if (!data)
 		return;
 
-	num_parents = of_clk_get_parent_count(node);
-
 	parent_names = kcalloc(num_parents, sizeof(char *), GFP_KERNEL);
 	if (!parent_names)
 		return;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/clk/clk-multiplier.c linux-libre-4.4.223-gnu/drivers/clk/clk-multiplier.c
--- linux-libre-4.4.222-gnu/drivers/clk/clk-multiplier.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/clk/clk-multiplier.c	2020-05-10 04:26:37.000000000 -0400
@@ -54,14 +54,28 @@ static unsigned long __bestmult(struct c
 				unsigned long *best_parent_rate,
 				u8 width, unsigned long flags)
 {
+	struct clk_multiplier *mult = to_clk_multiplier(hw);
 	unsigned long orig_parent_rate = *best_parent_rate;
 	unsigned long parent_rate, current_rate, best_rate = ~0;
 	unsigned int i, bestmult = 0;
+	unsigned int maxmult = (1 << width) - 1;
 
-	if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT))
-		return rate / *best_parent_rate;
+	if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
+		bestmult = rate / orig_parent_rate;
 
-	for (i = 1; i < ((1 << width) - 1); i++) {
+		/* Make sure we don't end up with a 0 multiplier */
+		if ((bestmult == 0) &&
+		    !(mult->flags & CLK_MULTIPLIER_ZERO_BYPASS))
+			bestmult = 1;
+
+		/* Make sure we don't overflow the multiplier */
+		if (bestmult > maxmult)
+			bestmult = maxmult;
+
+		return bestmult;
+	}
+
+	for (i = 1; i < maxmult; i++) {
 		if (rate == orig_parent_rate * i) {
 			/*
 			 * This is the best case for us if we have a
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/clk/clk-xgene.c linux-libre-4.4.223-gnu/drivers/clk/clk-xgene.c
--- linux-libre-4.4.222-gnu/drivers/clk/clk-xgene.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/clk/clk-xgene.c	2020-05-10 04:26:37.000000000 -0400
@@ -218,22 +218,20 @@ static int xgene_clk_enable(struct clk_h
 	struct xgene_clk *pclk = to_xgene_clk(hw);
 	unsigned long flags = 0;
 	u32 data;
-	phys_addr_t reg;
 
 	if (pclk->lock)
 		spin_lock_irqsave(pclk->lock, flags);
 
 	if (pclk->param.csr_reg != NULL) {
 		pr_debug("%s clock enabled\n", clk_hw_get_name(hw));
-		reg = __pa(pclk->param.csr_reg);
 		/* First enable the clock */
 		data = xgene_clk_read(pclk->param.csr_reg +
 					pclk->param.reg_clk_offset);
 		data |= pclk->param.reg_clk_mask;
 		xgene_clk_write(data, pclk->param.csr_reg +
 					pclk->param.reg_clk_offset);
-		pr_debug("%s clock PADDR base %pa clk offset 0x%08X mask 0x%08X value 0x%08X\n",
-			clk_hw_get_name(hw), &reg,
+		pr_debug("%s clk offset 0x%08X mask 0x%08X value 0x%08X\n",
+			clk_hw_get_name(hw),
 			pclk->param.reg_clk_offset, pclk->param.reg_clk_mask,
 			data);
 
@@ -243,8 +241,8 @@ static int xgene_clk_enable(struct clk_h
 		data &= ~pclk->param.reg_csr_mask;
 		xgene_clk_write(data, pclk->param.csr_reg +
 					pclk->param.reg_csr_offset);
-		pr_debug("%s CSR RESET PADDR base %pa csr offset 0x%08X mask 0x%08X value 0x%08X\n",
-			clk_hw_get_name(hw), &reg,
+		pr_debug("%s csr offset 0x%08X mask 0x%08X value 0x%08X\n",
+			clk_hw_get_name(hw),
 			pclk->param.reg_csr_offset, pclk->param.reg_csr_mask,
 			data);
 	}
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/clk/imx/clk-pllv3.c linux-libre-4.4.223-gnu/drivers/clk/imx/clk-pllv3.c
--- linux-libre-4.4.222-gnu/drivers/clk/imx/clk-pllv3.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/clk/imx/clk-pllv3.c	2020-05-10 04:26:37.000000000 -0400
@@ -76,9 +76,9 @@ static int clk_pllv3_prepare(struct clk_
 
 	val = readl_relaxed(pll->base);
 	if (pll->powerup_set)
-		val |= BM_PLL_POWER;
+		val |= pll->powerdown;
 	else
-		val &= ~BM_PLL_POWER;
+		val &= ~pll->powerdown;
 	writel_relaxed(val, pll->base);
 
 	return clk_pllv3_wait_lock(pll);
@@ -91,9 +91,9 @@ static void clk_pllv3_unprepare(struct c
 
 	val = readl_relaxed(pll->base);
 	if (pll->powerup_set)
-		val &= ~BM_PLL_POWER;
+		val &= ~pll->powerdown;
 	else
-		val |= BM_PLL_POWER;
+		val |= pll->powerdown;
 	writel_relaxed(val, pll->base);
 }
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/clk/rockchip/clk-mmc-phase.c linux-libre-4.4.223-gnu/drivers/clk/rockchip/clk-mmc-phase.c
--- linux-libre-4.4.222-gnu/drivers/clk/rockchip/clk-mmc-phase.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/clk/rockchip/clk-mmc-phase.c	2020-05-10 04:26:37.000000000 -0400
@@ -41,8 +41,6 @@ static unsigned long rockchip_mmc_recalc
 #define ROCKCHIP_MMC_DEGREE_MASK 0x3
 #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2
 #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
-#define ROCKCHIP_MMC_INIT_STATE_RESET 0x1
-#define ROCKCHIP_MMC_INIT_STATE_SHIFT 1
 
 #define PSECS_PER_SEC 1000000000000LL
 
@@ -183,15 +181,6 @@ struct clk *rockchip_clk_register_mmc(co
 	mmc_clock->reg = reg;
 	mmc_clock->shift = shift;
 
-	/*
-	 * Assert init_state to soft reset the CLKGEN
-	 * for mmc tuning phase and degree
-	 */
-	if (mmc_clock->shift == ROCKCHIP_MMC_INIT_STATE_SHIFT)
-		writel(HIWORD_UPDATE(ROCKCHIP_MMC_INIT_STATE_RESET,
-				     ROCKCHIP_MMC_INIT_STATE_RESET,
-				     mmc_clock->shift), mmc_clock->reg);
-
 	clk = clk_register(NULL, &mmc_clock->hw);
 	if (IS_ERR(clk))
 		goto err_free;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/clk/st/clkgen-fsyn.c linux-libre-4.4.223-gnu/drivers/clk/st/clkgen-fsyn.c
--- linux-libre-4.4.222-gnu/drivers/clk/st/clkgen-fsyn.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/clk/st/clkgen-fsyn.c	2020-05-10 04:26:37.000000000 -0400
@@ -549,19 +549,20 @@ static int clk_fs660c32_vco_get_params(u
 	return 0;
 }
 
-static long quadfs_pll_fs660c32_round_rate(struct clk_hw *hw, unsigned long rate
-		, unsigned long *prate)
+static long quadfs_pll_fs660c32_round_rate(struct clk_hw *hw,
+					   unsigned long rate,
+					   unsigned long *prate)
 {
 	struct stm_fs params;
 
-	if (!clk_fs660c32_vco_get_params(*prate, rate, &params))
-		clk_fs660c32_vco_get_rate(*prate, &params, &rate);
+	if (clk_fs660c32_vco_get_params(*prate, rate, &params))
+		return rate;
 
-	pr_debug("%s: %s new rate %ld [sdiv=0x%x,md=0x%x,pe=0x%x,nsdiv3=%u]\n",
+	clk_fs660c32_vco_get_rate(*prate, &params, &rate);
+
+	pr_debug("%s: %s new rate %ld [ndiv=%u]\n",
 		 __func__, clk_hw_get_name(hw),
-		 rate, (unsigned int)params.sdiv,
-		 (unsigned int)params.mdiv,
-		 (unsigned int)params.pe, (unsigned int)params.nsdiv);
+		 rate, (unsigned int)params.ndiv);
 
 	return rate;
 }
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/clk/ti/dpll3xxx.c linux-libre-4.4.223-gnu/drivers/clk/ti/dpll3xxx.c
--- linux-libre-4.4.222-gnu/drivers/clk/ti/dpll3xxx.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/clk/ti/dpll3xxx.c	2020-05-10 04:26:37.000000000 -0400
@@ -437,7 +437,8 @@ int omap3_noncore_dpll_enable(struct clk
 
 	parent = clk_hw_get_parent(hw);
 
-	if (clk_hw_get_rate(hw) == clk_get_rate(dd->clk_bypass)) {
+	if (clk_hw_get_rate(hw) ==
+	    clk_hw_get_rate(__clk_get_hw(dd->clk_bypass))) {
 		WARN_ON(parent != __clk_get_hw(dd->clk_bypass));
 		r = _omap3_noncore_dpll_bypass(clk);
 	} else {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/cpufreq/cpufreq.c linux-libre-4.4.223-gnu/drivers/cpufreq/cpufreq.c
--- linux-libre-4.4.222-gnu/drivers/cpufreq/cpufreq.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/cpufreq/cpufreq.c	2020-05-10 04:26:37.000000000 -0400
@@ -2171,10 +2171,7 @@ static int cpufreq_set_policy(struct cpu
 			return ret;
 		}
 
-		up_write(&policy->rwsem);
 		ret = __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT);
-		down_write(&policy->rwsem);
-
 		if (ret) {
 			pr_err("%s: Failed to Exit Governor: %s (%d)\n",
 			       __func__, old_gov->name, ret);
@@ -2190,9 +2187,7 @@ static int cpufreq_set_policy(struct cpu
 		if (!ret)
 			goto out;
 
-		up_write(&policy->rwsem);
 		__cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT);
-		down_write(&policy->rwsem);
 	}
 
 	/* new governor failed, so re-start old one */
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/dma/edma.c linux-libre-4.4.223-gnu/drivers/dma/edma.c
--- linux-libre-4.4.222-gnu/drivers/dma/edma.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/dma/edma.c	2020-05-10 04:26:37.000000000 -0400
@@ -2439,7 +2439,13 @@ static struct platform_driver edma_drive
 	},
 };
 
+static int edma_tptc_probe(struct platform_device *pdev)
+{
+	return 0;
+}
+
 static struct platform_driver edma_tptc_driver = {
+	.probe		= edma_tptc_probe,
 	.driver = {
 		.name	= "edma3-tptc",
 		.of_match_table = edma_tptc_of_ids,
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/gpu/drm/qxl/qxl_cmd.c linux-libre-4.4.223-gnu/drivers/gpu/drm/qxl/qxl_cmd.c
--- linux-libre-4.4.222-gnu/drivers/gpu/drm/qxl/qxl_cmd.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/gpu/drm/qxl/qxl_cmd.c	2020-05-10 04:26:37.000000000 -0400
@@ -529,8 +529,8 @@ int qxl_hw_surface_alloc(struct qxl_devi
 	/* no need to add a release to the fence for this surface bo,
 	   since it is only released when we ask to destroy the surface
 	   and it would never signal otherwise */
-	qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false);
 	qxl_release_fence_buffer_objects(release);
+	qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false);
 
 	surf->hw_surf_alloc = true;
 	spin_lock(&qdev->surf_id_idr_lock);
@@ -572,9 +572,8 @@ int qxl_hw_surface_dealloc(struct qxl_de
 	cmd->surface_id = id;
 	qxl_release_unmap(qdev, release, &cmd->release_info);
 
-	qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false);
-
 	qxl_release_fence_buffer_objects(release);
+	qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/gpu/drm/qxl/qxl_display.c linux-libre-4.4.223-gnu/drivers/gpu/drm/qxl/qxl_display.c
--- linux-libre-4.4.222-gnu/drivers/gpu/drm/qxl/qxl_display.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/gpu/drm/qxl/qxl_display.c	2020-05-10 04:26:37.000000000 -0400
@@ -292,8 +292,8 @@ qxl_hide_cursor(struct qxl_device *qdev)
 	cmd->type = QXL_CURSOR_HIDE;
 	qxl_release_unmap(qdev, release, &cmd->release_info);
 
-	qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
 	qxl_release_fence_buffer_objects(release);
+	qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
 	return 0;
 }
 
@@ -390,8 +390,8 @@ static int qxl_crtc_cursor_set2(struct d
 	cmd->u.set.visible = 1;
 	qxl_release_unmap(qdev, release, &cmd->release_info);
 
-	qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
 	qxl_release_fence_buffer_objects(release);
+	qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
 
 	/* finish with the userspace bo */
 	ret = qxl_bo_reserve(user_bo, false);
@@ -450,8 +450,8 @@ static int qxl_crtc_cursor_move(struct d
 	cmd->u.position.y = qcrtc->cur_y + qcrtc->hot_spot_y;
 	qxl_release_unmap(qdev, release, &cmd->release_info);
 
-	qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
 	qxl_release_fence_buffer_objects(release);
+	qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/gpu/drm/qxl/qxl_draw.c linux-libre-4.4.223-gnu/drivers/gpu/drm/qxl/qxl_draw.c
--- linux-libre-4.4.222-gnu/drivers/gpu/drm/qxl/qxl_draw.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/gpu/drm/qxl/qxl_draw.c	2020-05-10 04:26:37.000000000 -0400
@@ -245,8 +245,8 @@ void qxl_draw_opaque_fb(const struct qxl
 		qxl_bo_physical_address(qdev, dimage->bo, 0);
 	qxl_release_unmap(qdev, release, &drawable->release_info);
 
-	qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false);
 	qxl_release_fence_buffer_objects(release);
+	qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false);
 
 out_free_palette:
 	if (palette_bo)
@@ -352,9 +352,10 @@ void qxl_draw_dirty_fb(struct qxl_device
 		goto out_release_backoff;
 
 	rects = drawable_set_clipping(qdev, drawable, num_clips, clips_bo);
-	if (!rects)
+	if (!rects) {
+		ret = -EINVAL;
 		goto out_release_backoff;
-
+	}
 	drawable = (struct qxl_drawable *)qxl_release_map(qdev, release);
 
 	drawable->clip.type = SPICE_CLIP_TYPE_RECTS;
@@ -385,8 +386,8 @@ void qxl_draw_dirty_fb(struct qxl_device
 	}
 	qxl_bo_kunmap(clips_bo);
 
-	qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false);
 	qxl_release_fence_buffer_objects(release);
+	qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false);
 
 out_release_backoff:
 	if (ret)
@@ -436,8 +437,8 @@ void qxl_draw_copyarea(struct qxl_device
 	drawable->u.copy_bits.src_pos.y = sy;
 	qxl_release_unmap(qdev, release, &drawable->release_info);
 
-	qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false);
 	qxl_release_fence_buffer_objects(release);
+	qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false);
 
 out_free_release:
 	if (ret)
@@ -480,8 +481,8 @@ void qxl_draw_fill(struct qxl_draw_fill
 
 	qxl_release_unmap(qdev, release, &drawable->release_info);
 
-	qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false);
 	qxl_release_fence_buffer_objects(release);
+	qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false);
 
 out_free_release:
 	if (ret)
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/gpu/drm/qxl/qxl_ioctl.c linux-libre-4.4.223-gnu/drivers/gpu/drm/qxl/qxl_ioctl.c
--- linux-libre-4.4.222-gnu/drivers/gpu/drm/qxl/qxl_ioctl.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/gpu/drm/qxl/qxl_ioctl.c	2020-05-10 04:26:37.000000000 -0400
@@ -257,11 +257,8 @@ static int qxl_process_single_command(st
 			apply_surf_reloc(qdev, &reloc_info[i]);
 	}
 
+	qxl_release_fence_buffer_objects(release);
 	ret = qxl_push_command_ring_release(qdev, release, cmd->type, true);
-	if (ret)
-		qxl_release_backoff_reserve_list(release);
-	else
-		qxl_release_fence_buffer_objects(release);
 
 out_free_bos:
 out_free_release:
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/hv/hv_utils_transport.c linux-libre-4.4.223-gnu/drivers/hv/hv_utils_transport.c
--- linux-libre-4.4.222-gnu/drivers/hv/hv_utils_transport.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/hv/hv_utils_transport.c	2020-05-10 04:26:37.000000000 -0400
@@ -80,11 +80,10 @@ static ssize_t hvt_op_write(struct file
 
 	hvt = container_of(file->f_op, struct hvutil_transport, fops);
 
-	inmsg = kzalloc(count, GFP_KERNEL);
-	if (copy_from_user(inmsg, buf, count)) {
-		kfree(inmsg);
-		return -EFAULT;
-	}
+	inmsg = memdup_user(buf, count);
+	if (IS_ERR(inmsg))
+		return PTR_ERR(inmsg);
+
 	if (hvt->on_msg(inmsg, count))
 		return -EFAULT;
 	kfree(inmsg);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/iio/adc/ad7793.c linux-libre-4.4.223-gnu/drivers/iio/adc/ad7793.c
--- linux-libre-4.4.222-gnu/drivers/iio/adc/ad7793.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/iio/adc/ad7793.c	2020-05-10 04:26:37.000000000 -0400
@@ -579,7 +579,7 @@ static const struct iio_info ad7797_info
 	.read_raw = &ad7793_read_raw,
 	.write_raw = &ad7793_write_raw,
 	.write_raw_get_fmt = &ad7793_write_raw_get_fmt,
-	.attrs = &ad7793_attribute_group,
+	.attrs = &ad7797_attribute_group,
 	.validate_trigger = ad_sd_validate_trigger,
 	.driver_module = THIS_MODULE,
 };
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/infiniband/hw/cxgb3/cxio_hal.c linux-libre-4.4.223-gnu/drivers/infiniband/hw/cxgb3/cxio_hal.c
--- linux-libre-4.4.222-gnu/drivers/infiniband/hw/cxgb3/cxio_hal.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/infiniband/hw/cxgb3/cxio_hal.c	2020-05-10 04:26:37.000000000 -0400
@@ -327,7 +327,7 @@ int cxio_destroy_cq(struct cxio_rdev *rd
 	kfree(cq->sw_queue);
 	dma_free_coherent(&(rdev_p->rnic_info.pdev->dev),
 			  (1UL << (cq->size_log2))
-			  * sizeof(struct t3_cqe), cq->queue,
+			  * sizeof(struct t3_cqe) + 1, cq->queue,
 			  dma_unmap_addr(cq, mapping));
 	cxio_hal_put_cqid(rdev_p->rscp, cq->cqid);
 	return err;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/infiniband/hw/mlx4/ah.c linux-libre-4.4.223-gnu/drivers/infiniband/hw/mlx4/ah.c
--- linux-libre-4.4.222-gnu/drivers/infiniband/hw/mlx4/ah.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/infiniband/hw/mlx4/ah.c	2020-05-10 04:26:37.000000000 -0400
@@ -107,6 +107,7 @@ static struct ib_ah *create_iboe_ah(stru
 		return ERR_PTR(ret);
 	ah->av.eth.gid_index = ret;
 	ah->av.eth.vlan = cpu_to_be16(vlan_tag);
+	ah->av.eth.hop_limit = ah_attr->grh.hop_limit;
 	if (ah_attr->static_rate) {
 		ah->av.eth.stat_rate = ah_attr->static_rate + MLX4_STAT_RATE_OFFSET;
 		while (ah->av.eth.stat_rate > IB_RATE_2_5_GBPS + MLX4_STAT_RATE_OFFSET &&
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/infiniband/hw/mlx5/main.c linux-libre-4.4.223-gnu/drivers/infiniband/hw/mlx5/main.c
--- linux-libre-4.4.222-gnu/drivers/infiniband/hw/mlx5/main.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/infiniband/hw/mlx5/main.c	2020-05-10 04:26:37.000000000 -0400
@@ -905,7 +905,7 @@ static ssize_t show_fw_ver(struct device
 {
 	struct mlx5_ib_dev *dev =
 		container_of(device, struct mlx5_ib_dev, ib_dev.dev);
-	return sprintf(buf, "%d.%d.%d\n", fw_rev_maj(dev->mdev),
+	return sprintf(buf, "%d.%d.%04d\n", fw_rev_maj(dev->mdev),
 		       fw_rev_min(dev->mdev), fw_rev_sub(dev->mdev));
 }
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/infiniband/hw/mlx5/qp.c linux-libre-4.4.223-gnu/drivers/infiniband/hw/mlx5/qp.c
--- linux-libre-4.4.222-gnu/drivers/infiniband/hw/mlx5/qp.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/infiniband/hw/mlx5/qp.c	2020-05-10 04:26:37.000000000 -0400
@@ -271,8 +271,10 @@ static int sq_overhead(enum ib_qp_type q
 		/* fall through */
 	case IB_QPT_RC:
 		size += sizeof(struct mlx5_wqe_ctrl_seg) +
-			sizeof(struct mlx5_wqe_atomic_seg) +
-			sizeof(struct mlx5_wqe_raddr_seg);
+			max(sizeof(struct mlx5_wqe_atomic_seg) +
+			    sizeof(struct mlx5_wqe_raddr_seg),
+			    sizeof(struct mlx5_wqe_umr_ctrl_seg) +
+			    sizeof(struct mlx5_mkey_seg));
 		break;
 
 	case IB_QPT_XRC_TGT:
@@ -280,9 +282,9 @@ static int sq_overhead(enum ib_qp_type q
 
 	case IB_QPT_UC:
 		size += sizeof(struct mlx5_wqe_ctrl_seg) +
-			sizeof(struct mlx5_wqe_raddr_seg) +
-			sizeof(struct mlx5_wqe_umr_ctrl_seg) +
-			sizeof(struct mlx5_mkey_seg);
+			max(sizeof(struct mlx5_wqe_raddr_seg),
+			    sizeof(struct mlx5_wqe_umr_ctrl_seg) +
+			    sizeof(struct mlx5_mkey_seg));
 		break;
 
 	case IB_QPT_UD:
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/input/keyboard/gpio_keys.c linux-libre-4.4.223-gnu/drivers/input/keyboard/gpio_keys.c
--- linux-libre-4.4.222-gnu/drivers/input/keyboard/gpio_keys.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/input/keyboard/gpio_keys.c	2020-05-10 04:26:37.000000000 -0400
@@ -96,7 +96,7 @@ struct gpio_keys_drvdata {
  * Return value of this function can be used to allocate bitmap
  * large enough to hold all bits for given type.
  */
-static inline int get_n_events_by_type(int type)
+static int get_n_events_by_type(int type)
 {
 	BUG_ON(type != EV_SW && type != EV_KEY);
 
@@ -104,6 +104,22 @@ static inline int get_n_events_by_type(i
 }
 
 /**
+ * get_bm_events_by_type() - returns bitmap of supported events per @type
+ * @input: input device from which bitmap is retrieved
+ * @type: type of button (%EV_KEY, %EV_SW)
+ *
+ * Return value of this function can be used to allocate bitmap
+ * large enough to hold all bits for given type.
+ */
+static const unsigned long *get_bm_events_by_type(struct input_dev *dev,
+						  int type)
+{
+	BUG_ON(type != EV_SW && type != EV_KEY);
+
+	return (type == EV_KEY) ? dev->keybit : dev->swbit;
+}
+
+/**
  * gpio_keys_disable_button() - disables given GPIO button
  * @bdata: button data for button to be disabled
  *
@@ -213,6 +229,7 @@ static ssize_t gpio_keys_attr_store_help
 					   const char *buf, unsigned int type)
 {
 	int n_events = get_n_events_by_type(type);
+	const unsigned long *bitmap = get_bm_events_by_type(ddata->input, type);
 	unsigned long *bits;
 	ssize_t error;
 	int i;
@@ -226,6 +243,11 @@ static ssize_t gpio_keys_attr_store_help
 		goto out;
 
 	/* First validate */
+	if (!bitmap_subset(bits, bitmap, n_events)) {
+		error = -EINVAL;
+		goto out;
+	}
+
 	for (i = 0; i < ddata->pdata->nbuttons; i++) {
 		struct gpio_button_data *bdata = &ddata->data[i];
 
@@ -239,11 +261,6 @@ static ssize_t gpio_keys_attr_store_help
 		}
 	}
 
-	if (i == ddata->pdata->nbuttons) {
-		error = -EINVAL;
-		goto out;
-	}
-
 	mutex_lock(&ddata->disable_lock);
 
 	for (i = 0; i < ddata->pdata->nbuttons; i++) {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/input/touchscreen/edt-ft5x06.c linux-libre-4.4.223-gnu/drivers/input/touchscreen/edt-ft5x06.c
--- linux-libre-4.4.222-gnu/drivers/input/touchscreen/edt-ft5x06.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/input/touchscreen/edt-ft5x06.c	2020-05-10 04:26:37.000000000 -0400
@@ -822,16 +822,22 @@ static void edt_ft5x06_ts_get_defaults(s
 	int error;
 
 	error = device_property_read_u32(dev, "threshold", &val);
-	if (!error)
-		reg_addr->reg_threshold = val;
+	if (!error) {
+		edt_ft5x06_register_write(tsdata, reg_addr->reg_threshold, val);
+		tsdata->threshold = val;
+	}
 
 	error = device_property_read_u32(dev, "gain", &val);
-	if (!error)
-		reg_addr->reg_gain = val;
+	if (!error) {
+		edt_ft5x06_register_write(tsdata, reg_addr->reg_gain, val);
+		tsdata->gain = val;
+	}
 
 	error = device_property_read_u32(dev, "offset", &val);
-	if (!error)
-		reg_addr->reg_offset = val;
+	if (!error) {
+		edt_ft5x06_register_write(tsdata, reg_addr->reg_offset, val);
+		tsdata->offset = val;
+	}
 }
 
 static void
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/iommu/dma-iommu.c linux-libre-4.4.223-gnu/drivers/iommu/dma-iommu.c
--- linux-libre-4.4.222-gnu/drivers/iommu/dma-iommu.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/iommu/dma-iommu.c	2020-05-10 04:26:37.000000000 -0400
@@ -152,12 +152,15 @@ int dma_direction_to_prot(enum dma_data_
 	}
 }
 
-static struct iova *__alloc_iova(struct iova_domain *iovad, size_t size,
+static struct iova *__alloc_iova(struct iommu_domain *domain, size_t size,
 		dma_addr_t dma_limit)
 {
+	struct iova_domain *iovad = domain->iova_cookie;
 	unsigned long shift = iova_shift(iovad);
 	unsigned long length = iova_align(iovad, size) >> shift;
 
+	if (domain->geometry.force_aperture)
+		dma_limit = min(dma_limit, domain->geometry.aperture_end);
 	/*
 	 * Enforce size-alignment to be safe - there could perhaps be an
 	 * attribute to control this per-device, or at least per-domain...
@@ -297,7 +300,7 @@ struct page **iommu_dma_alloc(struct dev
 	if (!pages)
 		return NULL;
 
-	iova = __alloc_iova(iovad, size, dev->coherent_dma_mask);
+	iova = __alloc_iova(domain, size, dev->coherent_dma_mask);
 	if (!iova)
 		goto out_free_pages;
 
@@ -369,7 +372,7 @@ dma_addr_t iommu_dma_map_page(struct dev
 	phys_addr_t phys = page_to_phys(page) + offset;
 	size_t iova_off = iova_offset(iovad, phys);
 	size_t len = iova_align(iovad, size + iova_off);
-	struct iova *iova = __alloc_iova(iovad, len, dma_get_mask(dev));
+	struct iova *iova = __alloc_iova(domain, len, dma_get_mask(dev));
 
 	if (!iova)
 		return DMA_ERROR_CODE;
@@ -483,7 +486,7 @@ int iommu_dma_map_sg(struct device *dev,
 		prev = s;
 	}
 
-	iova = __alloc_iova(iovad, iova_len, dma_get_mask(dev));
+	iova = __alloc_iova(domain, iova_len, dma_get_mask(dev));
 	if (!iova)
 		goto out_restore_sg;
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/md/dm.c linux-libre-4.4.223-gnu/drivers/md/dm.c
--- linux-libre-4.4.222-gnu/drivers/md/dm.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/md/dm.c	2020-05-10 04:26:37.000000000 -0400
@@ -2192,7 +2192,7 @@ static void dm_request_fn(struct request
 	goto out;
 
 delay_and_out:
-	blk_delay_queue(q, HZ / 100);
+	blk_delay_queue(q, 10);
 out:
 	dm_put_live_table(md, srcu_idx);
 }
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/media/pci/cx23885/cx23885-av.c linux-libre-4.4.223-gnu/drivers/media/pci/cx23885/cx23885-av.c
--- linux-libre-4.4.222-gnu/drivers/media/pci/cx23885/cx23885-av.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/media/pci/cx23885/cx23885-av.c	2020-05-10 04:26:37.000000000 -0400
@@ -24,7 +24,7 @@ void cx23885_av_work_handler(struct work
 {
 	struct cx23885_dev *dev =
 			   container_of(work, struct cx23885_dev, cx25840_work);
-	bool handled;
+	bool handled = false;
 
 	v4l2_subdev_call(dev->sd_cx25840, core, interrupt_service_routine,
 			 PCI_MSK_AV_CORE, &handled);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/media/platform/am437x/am437x-vpfe.c linux-libre-4.4.223-gnu/drivers/media/platform/am437x/am437x-vpfe.c
--- linux-libre-4.4.222-gnu/drivers/media/platform/am437x/am437x-vpfe.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/media/platform/am437x/am437x-vpfe.c	2020-05-10 04:26:37.000000000 -0400
@@ -1047,7 +1047,7 @@ static int vpfe_get_ccdc_image_format(st
 static int vpfe_config_ccdc_image_format(struct vpfe_device *vpfe)
 {
 	enum ccdc_frmfmt frm_fmt = CCDC_FRMFMT_INTERLACED;
-	int ret;
+	int ret = 0;
 
 	vpfe_dbg(2, vpfe, "vpfe_config_ccdc_image_format\n");
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c linux-libre-4.4.223-gnu/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
--- linux-libre-4.4.222-gnu/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c	2020-05-05 15:23:47.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c	2020-05-10 18:54:36.000000000 -0400
@@ -49,7 +49,7 @@
 #define PID_TABLE_SIZE 1024
 #define POLL_MSECS 50
 
-static int load_c8sectpfe_fw_step1(struct c8sectpfei *fei);
+static int load_c8sectpfe_fw(struct c8sectpfei *fei);
 
 #define TS_PKT_SIZE 188
 #define HEADER_SIZE (4)
@@ -143,6 +143,7 @@ static int c8sectpfe_start_feed(struct d
 	struct channel_info *channel;
 	u32 tmp;
 	unsigned long *bitmap;
+	int ret;
 
 	switch (dvbdmxfeed->type) {
 	case DMX_TYPE_TS:
@@ -171,8 +172,9 @@ static int c8sectpfe_start_feed(struct d
 	}
 
 	if (!atomic_read(&fei->fw_loaded)) {
-		dev_err(fei->dev, "%s: c8sectpfe fw not loaded\n", __func__);
-		return -EINVAL;
+		ret = load_c8sectpfe_fw(fei);
+		if (ret)
+			return ret;
 	}
 
 	mutex_lock(&fei->lock);
@@ -267,8 +269,9 @@ static int c8sectpfe_stop_feed(struct dv
 	unsigned long *bitmap;
 
 	if (!atomic_read(&fei->fw_loaded)) {
-		dev_err(fei->dev, "%s: c8sectpfe fw not loaded\n", __func__);
-		return -EINVAL;
+		ret = load_c8sectpfe_fw(fei);
+		if (ret)
+			return ret;
 	}
 
 	mutex_lock(&fei->lock);
@@ -882,13 +885,6 @@ static int c8sectpfe_probe(struct platfo
 		goto err_clk_disable;
 	}
 
-	/* ensure all other init has been done before requesting firmware */
-	ret = load_c8sectpfe_fw_step1(fei);
-	if (ret) {
-		dev_err(dev, "Couldn't load slim core firmware\n");
-		goto err_clk_disable;
-	}
-
 	c8sectpfe_debugfs_init(fei);
 
 	return 0;
@@ -1093,15 +1089,14 @@ static void load_dmem_segment(struct c8s
 		phdr->p_memsz - phdr->p_filesz);
 }
 
-static int load_slim_core_fw(const struct firmware *fw, void *context)
+static int load_slim_core_fw(const struct firmware *fw, struct c8sectpfei *fei)
 {
-	struct c8sectpfei *fei = context;
 	Elf32_Ehdr *ehdr;
 	Elf32_Phdr *phdr;
 	u8 __iomem *dst;
 	int err = 0, i;
 
-	if (!fw || !context)
+	if (!fw || !fei)
 		return -EINVAL;
 
 	ehdr = (Elf32_Ehdr *)fw->data;
@@ -1153,29 +1148,35 @@ static int load_slim_core_fw(const struc
 	return err;
 }
 
-static void load_c8sectpfe_fw_cb(const struct firmware *fw, void *context)
+static int load_c8sectpfe_fw(struct c8sectpfei *fei)
 {
-	struct c8sectpfei *fei = context;
+	const struct firmware *fw;
 	int err;
 
+	dev_info(fei->dev, "Loading firmware: %s\n", FIRMWARE_MEMDMA);
+
+	err = reject_firmware(&fw, FIRMWARE_MEMDMA, fei->dev);
+	if (err)
+		return err;
+
 	err = c8sectpfe_elf_sanity_check(fei, fw);
 	if (err) {
 		dev_err(fei->dev, "c8sectpfe_elf_sanity_check failed err=(%d)\n"
 			, err);
-		goto err;
+		return err;
 	}
 
-	err = load_slim_core_fw(fw, context);
+	err = load_slim_core_fw(fw, fei);
 	if (err) {
 		dev_err(fei->dev, "load_slim_core_fw failed err=(%d)\n", err);
-		goto err;
+		return err;
 	}
 
 	/* now the firmware is loaded configure the input blocks */
 	err = configure_channels(fei);
 	if (err) {
 		dev_err(fei->dev, "configure_channels failed err=(%d)\n", err);
-		goto err;
+		return err;
 	}
 
 	/*
@@ -1188,28 +1189,6 @@ static void load_c8sectpfe_fw_cb(const s
 	writel(0x1,  fei->io + DMA_CPU_RUN);
 
 	atomic_set(&fei->fw_loaded, 1);
-err:
-	complete_all(&fei->fw_ack);
-}
-
-static int load_c8sectpfe_fw_step1(struct c8sectpfei *fei)
-{
-	int err;
-
-	dev_info(fei->dev, "Loading firmware: %s\n", FIRMWARE_MEMDMA);
-
-	init_completion(&fei->fw_ack);
-	atomic_set(&fei->fw_loaded, 0);
-
-	err = reject_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
-				FIRMWARE_MEMDMA, fei->dev, GFP_KERNEL, fei,
-				load_c8sectpfe_fw_cb);
-
-	if (err) {
-		dev_err(fei->dev, "request_firmware_nowait err: %d.\n", err);
-		complete_all(&fei->fw_ack);
-		return err;
-	}
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/media/rc/rc-main.c linux-libre-4.4.223-gnu/drivers/media/rc/rc-main.c
--- linux-libre-4.4.222-gnu/drivers/media/rc/rc-main.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/media/rc/rc-main.c	2020-05-10 04:26:37.000000000 -0400
@@ -61,7 +61,7 @@ struct rc_map *rc_map_get(const char *na
 	struct rc_map_list *map;
 
 	map = seek_rc_map(name);
-#ifdef MODULE
+#ifdef CONFIG_MODULES
 	if (!map) {
 		int rc = request_module("%s", name);
 		if (rc < 0) {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/memory/tegra/tegra124.c linux-libre-4.4.223-gnu/drivers/memory/tegra/tegra124.c
--- linux-libre-4.4.222-gnu/drivers/memory/tegra/tegra124.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/memory/tegra/tegra124.c	2020-05-10 04:26:37.000000000 -0400
@@ -1007,6 +1007,7 @@ static const struct tegra_smmu_soc tegra
 	.num_swgroups = ARRAY_SIZE(tegra124_swgroups),
 	.supports_round_robin_arbitration = true,
 	.supports_request_limit = true,
+	.num_tlb_lines = 32,
 	.num_asids = 128,
 };
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/mfd/lp8788-irq.c linux-libre-4.4.223-gnu/drivers/mfd/lp8788-irq.c
--- linux-libre-4.4.222-gnu/drivers/mfd/lp8788-irq.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/mfd/lp8788-irq.c	2020-05-10 04:26:37.000000000 -0400
@@ -112,7 +112,7 @@ static irqreturn_t lp8788_irq_handler(in
 	struct lp8788_irq_data *irqd = ptr;
 	struct lp8788 *lp = irqd->lp;
 	u8 status[NUM_REGS], addr, mask;
-	bool handled;
+	bool handled = false;
 	int i;
 
 	if (lp8788_read_multi_bytes(lp, LP8788_INT_1, status, NUM_REGS))
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/misc/cxl/fault.c linux-libre-4.4.223-gnu/drivers/misc/cxl/fault.c
--- linux-libre-4.4.222-gnu/drivers/misc/cxl/fault.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/misc/cxl/fault.c	2020-05-10 04:26:37.000000000 -0400
@@ -152,7 +152,7 @@ static void cxl_handle_page_fault(struct
 	access = _PAGE_PRESENT;
 	if (dsisr & CXL_PSL_DSISR_An_S)
 		access |= _PAGE_RW;
-	if ((!ctx->kernel) || ~(dar & (1ULL << 63)))
+	if ((!ctx->kernel) || (REGION_ID(dar) == USER_REGION_ID))
 		access |= _PAGE_USER;
 
 	if (dsisr & DSISR_NOHPTE)
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/mmc/card/block.c linux-libre-4.4.223-gnu/drivers/mmc/card/block.c
--- linux-libre-4.4.222-gnu/drivers/mmc/card/block.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/mmc/card/block.c	2020-05-10 04:26:37.000000000 -0400
@@ -668,8 +668,10 @@ static int mmc_blk_ioctl_multi_cmd(struc
 	}
 
 	md = mmc_blk_get(bdev->bd_disk);
-	if (!md)
+	if (!md) {
+		err = -EINVAL;
 		goto cmd_err;
+	}
 
 	card = md->queue.card;
 	if (IS_ERR(card)) {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/mmc/core/debugfs.c linux-libre-4.4.223-gnu/drivers/mmc/core/debugfs.c
--- linux-libre-4.4.222-gnu/drivers/mmc/core/debugfs.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/mmc/core/debugfs.c	2020-05-10 04:26:37.000000000 -0400
@@ -170,7 +170,7 @@ static int mmc_ios_show(struct seq_file
 		str = "invalid";
 		break;
 	}
-	seq_printf(s, "signal voltage:\t%u (%s)\n", ios->chip_select, str);
+	seq_printf(s, "signal voltage:\t%u (%s)\n", ios->signal_voltage, str);
 
 	switch (ios->drv_type) {
 	case MMC_SET_DRIVER_TYPE_A:
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/mmc/core/sd.c linux-libre-4.4.223-gnu/drivers/mmc/core/sd.c
--- linux-libre-4.4.222-gnu/drivers/mmc/core/sd.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/mmc/core/sd.c	2020-05-10 04:26:37.000000000 -0400
@@ -337,6 +337,7 @@ static int mmc_read_switch(struct mmc_ca
 		card->sw_caps.sd3_bus_mode = status[13];
 		/* Driver Strengths supported by the card */
 		card->sw_caps.sd3_drv_type = status[9];
+		card->sw_caps.sd3_curr_limit = status[7] | status[6] << 8;
 	}
 
 out:
@@ -553,14 +554,25 @@ static int sd_set_current_limit(struct m
 	 * when we set current limit to 200ma, the card will draw 200ma, and
 	 * when we set current limit to 400/600/800ma, the card will draw its
 	 * maximum 300ma from the host.
+	 *
+	 * The above is incorrect: if we try to set a current limit that is
+	 * not supported by the card, the card can rightfully error out the
+	 * attempt, and remain at the default current limit.  This results
+	 * in a 300mA card being limited to 200mA even though the host
+	 * supports 800mA. Failures seen with SanDisk 8GB UHS cards with
+	 * an iMX6 host. --rmk
 	 */
-	if (max_current >= 800)
+	if (max_current >= 800 &&
+	    card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_800)
 		current_limit = SD_SET_CURRENT_LIMIT_800;
-	else if (max_current >= 600)
+	else if (max_current >= 600 &&
+		 card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_600)
 		current_limit = SD_SET_CURRENT_LIMIT_600;
-	else if (max_current >= 400)
+	else if (max_current >= 400 &&
+		 card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_400)
 		current_limit = SD_SET_CURRENT_LIMIT_400;
-	else if (max_current >= 200)
+	else if (max_current >= 200 &&
+		 card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_200)
 		current_limit = SD_SET_CURRENT_LIMIT_200;
 
 	if (current_limit != SD_SET_CURRENT_NO_CHANGE) {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/mmc/host/dw_mmc-rockchip.c linux-libre-4.4.223-gnu/drivers/mmc/host/dw_mmc-rockchip.c
--- linux-libre-4.4.222-gnu/drivers/mmc/host/dw_mmc-rockchip.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/mmc/host/dw_mmc-rockchip.c	2020-05-10 04:26:37.000000000 -0400
@@ -78,6 +78,70 @@ static void dw_mci_rk3288_set_ios(struct
 	/* Make sure we use phases which we can enumerate with */
 	if (!IS_ERR(priv->sample_clk))
 		clk_set_phase(priv->sample_clk, priv->default_sample_phase);
+
+	/*
+	 * Set the drive phase offset based on speed mode to achieve hold times.
+	 *
+	 * NOTE: this is _not_ a value that is dynamically tuned and is also
+	 * _not_ a value that will vary from board to board.  It is a value
+	 * that could vary between different SoC models if they had massively
+	 * different output clock delays inside their dw_mmc IP block (delay_o),
+	 * but since it's OK to overshoot a little we don't need to do complex
+	 * calculations and can pick values that will just work for everyone.
+	 *
+	 * When picking values we'll stick with picking 0/90/180/270 since
+	 * those can be made very accurately on all known Rockchip SoCs.
+	 *
+	 * Note that these values match values from the DesignWare Databook
+	 * tables for the most part except for SDR12 and "ID mode".  For those
+	 * two modes the databook calculations assume a clock in of 50MHz.  As
+	 * seen above, we always use a clock in rate that is exactly the
+	 * card's input clock (times RK3288_CLKGEN_DIV, but that gets divided
+	 * back out before the controller sees it).
+	 *
+	 * From measurement of a single device, it appears that delay_o is
+	 * about .5 ns.  Since we try to leave a bit of margin, it's expected
+	 * that numbers here will be fine even with much larger delay_o
+	 * (the 1.4 ns assumed by the DesignWare Databook would result in the
+	 * same results, for instance).
+	 */
+	if (!IS_ERR(priv->drv_clk)) {
+		int phase;
+
+		/*
+		 * In almost all cases a 90 degree phase offset will provide
+		 * sufficient hold times across all valid input clock rates
+		 * assuming delay_o is not absurd for a given SoC.  We'll use
+		 * that as a default.
+		 */
+		phase = 90;
+
+		switch (ios->timing) {
+		case MMC_TIMING_MMC_DDR52:
+			/*
+			 * Since clock in rate with MMC_DDR52 is doubled when
+			 * bus width is 8 we need to double the phase offset
+			 * to get the same timings.
+			 */
+			if (ios->bus_width == MMC_BUS_WIDTH_8)
+				phase = 180;
+			break;
+		case MMC_TIMING_UHS_SDR104:
+		case MMC_TIMING_MMC_HS200:
+			/*
+			 * In the case of 150 MHz clock (typical max for
+			 * Rockchip SoCs), 90 degree offset will add a delay
+			 * of 1.67 ns.  That will meet min hold time of .8 ns
+			 * as long as clock output delay is < .87 ns.  On
+			 * SoCs measured this seems to be OK, but it doesn't
+			 * hurt to give margin here, so we use 180.
+			 */
+			phase = 180;
+			break;
+		}
+
+		clk_set_phase(priv->drv_clk, phase);
+	}
 }
 
 #define NUM_PHASES			360
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/mmc/host/moxart-mmc.c linux-libre-4.4.223-gnu/drivers/mmc/host/moxart-mmc.c
--- linux-libre-4.4.222-gnu/drivers/mmc/host/moxart-mmc.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/mmc/host/moxart-mmc.c	2020-05-10 04:26:37.000000000 -0400
@@ -257,7 +257,7 @@ static void moxart_dma_complete(void *pa
 static void moxart_transfer_dma(struct mmc_data *data, struct moxart_host *host)
 {
 	u32 len, dir_data, dir_slave;
-	unsigned long dma_time;
+	long dma_time;
 	struct dma_async_tx_descriptor *desc = NULL;
 	struct dma_chan *dma_chan;
 
@@ -397,7 +397,8 @@ static void moxart_prepare_data(struct m
 static void moxart_request(struct mmc_host *mmc, struct mmc_request *mrq)
 {
 	struct moxart_host *host = mmc_priv(mmc);
-	unsigned long pio_time, flags;
+	long pio_time;
+	unsigned long flags;
 	u32 status;
 
 	spin_lock_irqsave(&host->lock, flags);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/mmc/host/sdhci.c linux-libre-4.4.223-gnu/drivers/mmc/host/sdhci.c
--- linux-libre-4.4.222-gnu/drivers/mmc/host/sdhci.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/mmc/host/sdhci.c	2020-05-10 04:26:37.000000000 -0400
@@ -1284,24 +1284,25 @@ clock_set:
 }
 EXPORT_SYMBOL_GPL(sdhci_set_clock);
 
-static void sdhci_set_power(struct sdhci_host *host, unsigned char mode,
-			    unsigned short vdd)
+static void sdhci_set_power_reg(struct sdhci_host *host, unsigned char mode,
+				unsigned short vdd)
 {
 	struct mmc_host *mmc = host->mmc;
-	u8 pwr = 0;
 
-	if (!IS_ERR(mmc->supply.vmmc)) {
-		spin_unlock_irq(&host->lock);
-		mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
-		spin_lock_irq(&host->lock);
+	spin_unlock_irq(&host->lock);
+	mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
+	spin_lock_irq(&host->lock);
 
-		if (mode != MMC_POWER_OFF)
-			sdhci_writeb(host, SDHCI_POWER_ON, SDHCI_POWER_CONTROL);
-		else
-			sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
+	if (mode != MMC_POWER_OFF)
+		sdhci_writeb(host, SDHCI_POWER_ON, SDHCI_POWER_CONTROL);
+	else
+		sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
+}
 
-		return;
-	}
+void sdhci_set_power(struct sdhci_host *host, unsigned char mode,
+		     unsigned short vdd)
+{
+	u8 pwr = 0;
 
 	if (mode != MMC_POWER_OFF) {
 		switch (1 << vdd) {
@@ -1332,7 +1333,6 @@ static void sdhci_set_power(struct sdhci
 		sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
 		if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON)
 			sdhci_runtime_pm_bus_off(host);
-		vdd = 0;
 	} else {
 		/*
 		 * Spec says that we should clear the power reg before setting
@@ -1364,6 +1364,20 @@ static void sdhci_set_power(struct sdhci
 			mdelay(10);
 	}
 }
+EXPORT_SYMBOL_GPL(sdhci_set_power);
+
+static void __sdhci_set_power(struct sdhci_host *host, unsigned char mode,
+			      unsigned short vdd)
+{
+	struct mmc_host *mmc = host->mmc;
+
+	if (host->ops->set_power)
+		host->ops->set_power(host, mode, vdd);
+	else if (!IS_ERR(mmc->supply.vmmc))
+		sdhci_set_power_reg(host, mode, vdd);
+	else
+		sdhci_set_power(host, mode, vdd);
+}
 
 /*****************************************************************************\
  *                                                                           *
@@ -1512,7 +1526,7 @@ static void sdhci_do_set_ios(struct sdhc
 		}
 	}
 
-	sdhci_set_power(host, ios->power_mode, ios->vdd);
+	__sdhci_set_power(host, ios->power_mode, ios->vdd);
 
 	if (host->ops->platform_send_init_74_clocks)
 		host->ops->platform_send_init_74_clocks(host, ios->power_mode);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/mmc/host/sdhci.h linux-libre-4.4.223-gnu/drivers/mmc/host/sdhci.h
--- linux-libre-4.4.222-gnu/drivers/mmc/host/sdhci.h	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/mmc/host/sdhci.h	2020-05-10 04:26:37.000000000 -0400
@@ -529,6 +529,8 @@ struct sdhci_ops {
 #endif
 
 	void	(*set_clock)(struct sdhci_host *host, unsigned int clock);
+	void	(*set_power)(struct sdhci_host *host, unsigned char mode,
+			     unsigned short vdd);
 
 	int		(*enable_dma)(struct sdhci_host *host);
 	unsigned int	(*get_max_clock)(struct sdhci_host *host);
@@ -660,6 +662,8 @@ static inline bool sdhci_sdio_irq_enable
 }
 
 void sdhci_set_clock(struct sdhci_host *host, unsigned int clock);
+void sdhci_set_power(struct sdhci_host *host, unsigned char mode,
+		     unsigned short vdd);
 void sdhci_set_bus_width(struct sdhci_host *host, int width);
 void sdhci_reset(struct sdhci_host *host, u8 mask);
 void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/mmc/host/sdhci-pxav3.c linux-libre-4.4.223-gnu/drivers/mmc/host/sdhci-pxav3.c
--- linux-libre-4.4.222-gnu/drivers/mmc/host/sdhci-pxav3.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/mmc/host/sdhci-pxav3.c	2020-05-10 04:26:37.000000000 -0400
@@ -307,8 +307,30 @@ static void pxav3_set_uhs_signaling(stru
 		__func__, uhs, ctrl_2);
 }
 
+static void pxav3_set_power(struct sdhci_host *host, unsigned char mode,
+			    unsigned short vdd)
+{
+	struct mmc_host *mmc = host->mmc;
+	u8 pwr = host->pwr;
+
+	sdhci_set_power(host, mode, vdd);
+
+	if (host->pwr == pwr)
+		return;
+
+	if (host->pwr == 0)
+		vdd = 0;
+
+	if (!IS_ERR(mmc->supply.vmmc)) {
+		spin_unlock_irq(&host->lock);
+		mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
+		spin_lock_irq(&host->lock);
+	}
+}
+
 static const struct sdhci_ops pxav3_sdhci_ops = {
 	.set_clock = sdhci_set_clock,
+	.set_power = pxav3_set_power,
 	.platform_send_init_74_clocks = pxav3_gen_init_74_clocks,
 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
 	.set_bus_width = sdhci_set_bus_width,
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/mtd/nand/denali.c linux-libre-4.4.223-gnu/drivers/mtd/nand/denali.c
--- linux-libre-4.4.222-gnu/drivers/mtd/nand/denali.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/mtd/nand/denali.c	2020-05-10 04:26:37.000000000 -0400
@@ -1622,9 +1622,16 @@ EXPORT_SYMBOL(denali_init);
 /* driver exit point */
 void denali_remove(struct denali_nand_info *denali)
 {
+	/*
+	 * Pre-compute DMA buffer size to avoid any problems in case
+	 * nand_release() ever changes in a way that mtd->writesize and
+	 * mtd->oobsize are not reliable after this call.
+	 */
+	int bufsize = denali->mtd.writesize + denali->mtd.oobsize;
+
+	nand_release(&denali->mtd);
 	denali_irq_cleanup(denali->irq, denali);
-	dma_unmap_single(denali->dev, denali->buf.dma_buf,
-			 denali->mtd.writesize + denali->mtd.oobsize,
+	dma_unmap_single(denali->dev, denali->buf.dma_buf, bufsize,
 			 DMA_BIDIRECTIONAL);
 }
 EXPORT_SYMBOL(denali_remove);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/bonding/bond_3ad.c linux-libre-4.4.223-gnu/drivers/net/bonding/bond_3ad.c
--- linux-libre-4.4.222-gnu/drivers/net/bonding/bond_3ad.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/bonding/bond_3ad.c	2020-05-10 04:26:37.000000000 -0400
@@ -100,11 +100,14 @@ enum ad_link_speed_type {
 #define MAC_ADDRESS_EQUAL(A, B)	\
 	ether_addr_equal_64bits((const u8 *)A, (const u8 *)B)
 
-static struct mac_addr null_mac_addr = { { 0, 0, 0, 0, 0, 0 } };
+static const u8 null_mac_addr[ETH_ALEN + 2] __long_aligned = {
+	0, 0, 0, 0, 0, 0
+};
 static u16 ad_ticks_per_sec;
 static const int ad_delta_in_ticks = (AD_TIMER_INTERVAL * HZ) / 1000;
 
-static const u8 lacpdu_mcast_addr[ETH_ALEN] = MULTICAST_LACPDU_ADDR;
+static const u8 lacpdu_mcast_addr[ETH_ALEN + 2] __long_aligned =
+	MULTICAST_LACPDU_ADDR;
 
 /* ================= main 802.3ad protocol functions ================== */
 static int ad_lacpdu_send(struct port *port);
@@ -1701,7 +1704,7 @@ static void ad_clear_agg(struct aggregat
 		aggregator->is_individual = false;
 		aggregator->actor_admin_aggregator_key = 0;
 		aggregator->actor_oper_aggregator_key = 0;
-		aggregator->partner_system = null_mac_addr;
+		eth_zero_addr(aggregator->partner_system.mac_addr_value);
 		aggregator->partner_system_priority = 0;
 		aggregator->partner_oper_aggregator_key = 0;
 		aggregator->receive_state = 0;
@@ -1723,7 +1726,7 @@ static void ad_initialize_agg(struct agg
 	if (aggregator) {
 		ad_clear_agg(aggregator);
 
-		aggregator->aggregator_mac_address = null_mac_addr;
+		eth_zero_addr(aggregator->aggregator_mac_address.mac_addr_value);
 		aggregator->aggregator_identifier = 0;
 		aggregator->slave = NULL;
 	}
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/bonding/bond_alb.c linux-libre-4.4.223-gnu/drivers/net/bonding/bond_alb.c
--- linux-libre-4.4.222-gnu/drivers/net/bonding/bond_alb.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/bonding/bond_alb.c	2020-05-10 04:26:37.000000000 -0400
@@ -42,13 +42,10 @@
 
 
 
-#ifndef __long_aligned
-#define __long_aligned __attribute__((aligned((sizeof(long)))))
-#endif
-static const u8 mac_bcast[ETH_ALEN] __long_aligned = {
+static const u8 mac_bcast[ETH_ALEN + 2] __long_aligned = {
 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff
 };
-static const u8 mac_v6_allmcast[ETH_ALEN] __long_aligned = {
+static const u8 mac_v6_allmcast[ETH_ALEN + 2] __long_aligned = {
 	0x33, 0x33, 0x00, 0x00, 0x00, 0x01
 };
 static const int alb_delta_in_ticks = HZ / ALB_TIMER_TICKS_PER_SEC;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/bonding/bond_netlink.c linux-libre-4.4.223-gnu/drivers/net/bonding/bond_netlink.c
--- linux-libre-4.4.222-gnu/drivers/net/bonding/bond_netlink.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/bonding/bond_netlink.c	2020-05-10 04:26:37.000000000 -0400
@@ -628,8 +628,7 @@ static int bond_fill_info(struct sk_buff
 				goto nla_put_failure;
 
 			if (nla_put(skb, IFLA_BOND_AD_ACTOR_SYSTEM,
-				    sizeof(bond->params.ad_actor_system),
-				    &bond->params.ad_actor_system))
+				    ETH_ALEN, &bond->params.ad_actor_system))
 				goto nla_put_failure;
 		}
 		if (!bond_3ad_get_active_agg_info(bond, &info)) {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/dsa/mv88e6xxx.c linux-libre-4.4.223-gnu/drivers/net/dsa/mv88e6xxx.c
--- linux-libre-4.4.222-gnu/drivers/net/dsa/mv88e6xxx.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/dsa/mv88e6xxx.c	2020-05-10 04:26:37.000000000 -0400
@@ -2064,9 +2064,9 @@ static int mv88e6xxx_setup_port(struct d
 	 * the other bits clear.
 	 */
 	reg = 1 << port;
-	/* Disable learning for DSA and CPU ports */
-	if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port))
-		reg = PORT_ASSOC_VECTOR_LOCKED_PORT;
+	/* Disable learning for CPU port */
+	if (dsa_is_cpu_port(ds, port))
+		reg = 0;
 
 	ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_ASSOC_VECTOR, reg);
 	if (ret)
@@ -2150,7 +2150,8 @@ static int mv88e6xxx_setup_port(struct d
 	 * database, and allow every port to egress frames on all other ports.
 	 */
 	reg = BIT(ps->num_ports) - 1; /* all ports */
-	ret = _mv88e6xxx_port_vlan_map_set(ds, port, reg & ~port);
+	reg &= ~BIT(port); /* except itself */
+	ret = _mv88e6xxx_port_vlan_map_set(ds, port, reg);
 	if (ret)
 		goto abort;
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/agere/et131x.c linux-libre-4.4.223-gnu/drivers/net/ethernet/agere/et131x.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/agere/et131x.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/agere/et131x.c	2020-05-10 04:26:37.000000000 -0400
@@ -3854,7 +3854,7 @@ static void et131x_tx_timeout(struct net
 	unsigned long flags;
 
 	/* If the device is closed, ignore the timeout */
-	if (~(adapter->flags & FMP_ADAPTER_INTERRUPT_IN_USE))
+	if (!(adapter->flags & FMP_ADAPTER_INTERRUPT_IN_USE))
 		return;
 
 	/* Any nonrecoverable hardware error?
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/broadcom/bcmsysport.c linux-libre-4.4.223-gnu/drivers/net/ethernet/broadcom/bcmsysport.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/broadcom/bcmsysport.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/broadcom/bcmsysport.c	2020-05-10 04:26:37.000000000 -0400
@@ -396,7 +396,7 @@ static void bcm_sysport_get_stats(struct
 		else
 			p = (char *)priv;
 		p += s->stat_offset;
-		data[i] = *(u32 *)p;
+		data[i] = *(unsigned long *)p;
 	}
 }
 
@@ -526,7 +526,8 @@ static struct sk_buff *bcm_sysport_rx_re
 	dma_addr_t mapping;
 
 	/* Allocate a new SKB for a new packet */
-	skb = netdev_alloc_skb(priv->netdev, RX_BUF_LENGTH);
+	skb = __netdev_alloc_skb(priv->netdev, RX_BUF_LENGTH,
+				 GFP_ATOMIC | __GFP_NOWARN);
 	if (!skb) {
 		priv->mib.alloc_rx_buff_failed++;
 		netif_err(priv, rx_err, ndev, "SKB alloc failed\n");
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/broadcom/bnxt/bnxt.c linux-libre-4.4.223-gnu/drivers/net/ethernet/broadcom/bnxt/bnxt.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/broadcom/bnxt/bnxt.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/broadcom/bnxt/bnxt.c	2020-05-10 04:26:37.000000000 -0400
@@ -4250,6 +4250,10 @@ static void bnxt_del_napi(struct bnxt *b
 		napi_hash_del(&bnapi->napi);
 		netif_napi_del(&bnapi->napi);
 	}
+	/* We called napi_hash_del() before netif_napi_del(), we need
+	 * to respect an RCU grace period before freeing napi structures.
+	 */
+	synchronize_net();
 }
 
 static void bnxt_init_napi(struct bnxt *bp)
@@ -4306,9 +4310,7 @@ static void bnxt_tx_disable(struct bnxt
 			bnapi = bp->bnapi[i];
 			txr = &bnapi->tx_ring;
 			txq = netdev_get_tx_queue(bp->dev, i);
-			__netif_tx_lock(txq, smp_processor_id());
 			txr->dev_state = BNXT_DEV_STATE_CLOSING;
-			__netif_tx_unlock(txq);
 		}
 	}
 	/* Stop all TX queues */
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/broadcom/genet/bcmgenet.c linux-libre-4.4.223-gnu/drivers/net/ethernet/broadcom/genet/bcmgenet.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/broadcom/genet/bcmgenet.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/broadcom/genet/bcmgenet.c	2020-05-10 04:26:37.000000000 -0400
@@ -927,7 +927,11 @@ static void bcmgenet_get_ethtool_stats(s
 		else
 			p = (char *)priv;
 		p += s->stat_offset;
-		data[i] = *(u32 *)p;
+		if (sizeof(unsigned long) != sizeof(u32) &&
+		    s->stat_sizeof == sizeof(unsigned long))
+			data[i] = *(unsigned long *)p;
+		else
+			data[i] = *(u32 *)p;
 	}
 }
 
@@ -1346,7 +1350,7 @@ static int bcmgenet_xmit_single(struct n
 
 	tx_cb_ptr->skb = skb;
 
-	skb_len = skb_headlen(skb) < ETH_ZLEN ? ETH_ZLEN : skb_headlen(skb);
+	skb_len = skb_headlen(skb);
 
 	mapping = dma_map_single(kdev, skb->data, skb_len, DMA_TO_DEVICE);
 	ret = dma_mapping_error(kdev, mapping);
@@ -1575,7 +1579,8 @@ static struct sk_buff *bcmgenet_rx_refil
 	dma_addr_t mapping;
 
 	/* Allocate a new Rx skb */
-	skb = netdev_alloc_skb(priv->dev, priv->rx_buf_len + SKB_ALIGNMENT);
+	skb = __netdev_alloc_skb(priv->dev, priv->rx_buf_len + SKB_ALIGNMENT,
+				 GFP_ATOMIC | __GFP_NOWARN);
 	if (!skb) {
 		priv->mib.alloc_rx_buff_failed++;
 		netif_err(priv, rx_err, priv->dev,
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/brocade/bna/bnad_ethtool.c linux-libre-4.4.223-gnu/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/brocade/bna/bnad_ethtool.c	2020-05-05 15:28:10.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/brocade/bna/bnad_ethtool.c	2020-05-10 18:57:19.000000000 -0400
@@ -31,7 +31,7 @@
 #define BNAD_NUM_TXF_COUNTERS 12
 #define BNAD_NUM_RXF_COUNTERS 10
 #define BNAD_NUM_CQ_COUNTERS (3 + 5)
-#define BNAD_NUM_RXQ_COUNTERS 6
+#define BNAD_NUM_RXQ_COUNTERS 7
 #define BNAD_NUM_TXQ_COUNTERS 5
 
 #define BNAD_ETHTOOL_STATS_NUM						\
@@ -658,6 +658,8 @@ bnad_get_strings(struct net_device *netd
 				string += ETH_GSTRING_LEN;
 				sprintf(string, "rxq%d_allocbuf_failed", q_num);
 				string += ETH_GSTRING_LEN;
+				sprintf(string, "rxq%d_mapbuf_failed", q_num);
+				string += ETH_GSTRING_LEN;
 				sprintf(string, "rxq%d_producer_index", q_num);
 				string += ETH_GSTRING_LEN;
 				sprintf(string, "rxq%d_consumer_index", q_num);
@@ -678,6 +680,9 @@ bnad_get_strings(struct net_device *netd
 					sprintf(string, "rxq%d_allocbuf_failed",
 								q_num);
 					string += ETH_GSTRING_LEN;
+					sprintf(string, "rxq%d_mapbuf_failed",
+						q_num);
+					string += ETH_GSTRING_LEN;
 					sprintf(string, "rxq%d_producer_index",
 								q_num);
 					string += ETH_GSTRING_LEN;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/cadence/macb.c linux-libre-4.4.223-gnu/drivers/net/ethernet/cadence/macb.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/cadence/macb.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/cadence/macb.c	2020-05-10 04:26:37.000000000 -0400
@@ -1104,7 +1104,7 @@ static irqreturn_t macb_interrupt(int ir
 			macb_writel(bp, NCR, ctrl | MACB_BIT(RE));
 
 			if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
-				macb_writel(bp, ISR, MACB_BIT(RXUBR));
+				queue_writel(queue, ISR, MACB_BIT(RXUBR));
 		}
 
 		if (status & MACB_BIT(ISR_ROVR)) {
@@ -2904,7 +2904,7 @@ static int macb_probe(struct platform_de
 	dev->irq = platform_get_irq(pdev, 0);
 	if (dev->irq < 0) {
 		err = dev->irq;
-		goto err_disable_clocks;
+		goto err_out_free_netdev;
 	}
 
 	mac = of_get_mac_address(np);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/chelsio/cxgb4/sge.c linux-libre-4.4.223-gnu/drivers/net/ethernet/chelsio/cxgb4/sge.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/chelsio/cxgb4/sge.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/chelsio/cxgb4/sge.c	2020-05-10 04:26:37.000000000 -0400
@@ -1165,7 +1165,7 @@ out_free:	dev_kfree_skb_any(skb);
 
 	/* Discard the packet if the length is greater than mtu */
 	max_pkt_len = ETH_HLEN + dev->mtu;
-	if (skb_vlan_tag_present(skb))
+	if (skb_vlan_tagged(skb))
 		max_pkt_len += VLAN_HLEN;
 	if (!skb_shinfo(skb)->gso_size && (unlikely(skb->len > max_pkt_len)))
 		goto out_free;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/chelsio/cxgb4vf/sge.c linux-libre-4.4.223-gnu/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/chelsio/cxgb4vf/sge.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/chelsio/cxgb4vf/sge.c	2020-05-10 04:26:37.000000000 -0400
@@ -1188,7 +1188,7 @@ int t4vf_eth_xmit(struct sk_buff *skb, s
 
 	/* Discard the packet if the length is greater than mtu */
 	max_pkt_len = ETH_HLEN + dev->mtu;
-	if (skb_vlan_tag_present(skb))
+	if (skb_vlan_tagged(skb))
 		max_pkt_len += VLAN_HLEN;
 	if (!skb_shinfo(skb)->gso_size && (unlikely(skb->len > max_pkt_len)))
 		goto out_free;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/cirrus/ep93xx_eth.c linux-libre-4.4.223-gnu/drivers/net/ethernet/cirrus/ep93xx_eth.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/cirrus/ep93xx_eth.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/cirrus/ep93xx_eth.c	2020-05-10 04:26:37.000000000 -0400
@@ -468,6 +468,9 @@ static void ep93xx_free_buffers(struct e
 	struct device *dev = ep->dev->dev.parent;
 	int i;
 
+	if (!ep->descs)
+		return;
+
 	for (i = 0; i < RX_QUEUE_ENTRIES; i++) {
 		dma_addr_t d;
 
@@ -490,6 +493,7 @@ static void ep93xx_free_buffers(struct e
 
 	dma_free_coherent(dev, sizeof(struct ep93xx_descs), ep->descs,
 							ep->descs_dma_addr);
+	ep->descs = NULL;
 }
 
 static int ep93xx_alloc_buffers(struct ep93xx_priv *ep)
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/emulex/benet/be.h linux-libre-4.4.223-gnu/drivers/net/ethernet/emulex/benet/be.h
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/emulex/benet/be.h	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/emulex/benet/be.h	2020-05-10 04:26:37.000000000 -0400
@@ -531,6 +531,7 @@ struct be_adapter {
 
 	struct delayed_work be_err_detection_work;
 	u8 err_flags;
+	bool pcicfg_mapped;	/* pcicfg obtained via pci_iomap() */
 	u32 flags;
 	u32 cmd_privileges;
 	/* Ethtool knobs and info */
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/emulex/benet/be_main.c linux-libre-4.4.223-gnu/drivers/net/ethernet/emulex/benet/be_main.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/emulex/benet/be_main.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/emulex/benet/be_main.c	2020-05-10 04:26:37.000000000 -0400
@@ -5526,6 +5526,8 @@ static void be_unmap_pci_bars(struct be_
 		pci_iounmap(adapter->pdev, adapter->csr);
 	if (adapter->db)
 		pci_iounmap(adapter->pdev, adapter->db);
+	if (adapter->pcicfg && adapter->pcicfg_mapped)
+		pci_iounmap(adapter->pdev, adapter->pcicfg);
 }
 
 static int db_bar(struct be_adapter *adapter)
@@ -5577,8 +5579,10 @@ static int be_map_pci_bars(struct be_ada
 			if (!addr)
 				goto pci_map_err;
 			adapter->pcicfg = addr;
+			adapter->pcicfg_mapped = true;
 		} else {
 			adapter->pcicfg = adapter->db + SRIOV_VF_PCICFG_OFFSET;
+			adapter->pcicfg_mapped = false;
 		}
 	}
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/ethoc.c linux-libre-4.4.223-gnu/drivers/net/ethernet/ethoc.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/ethoc.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/ethoc.c	2020-05-10 04:26:37.000000000 -0400
@@ -1088,7 +1088,7 @@ static int ethoc_probe(struct platform_d
 	if (!priv->iobase) {
 		dev_err(&pdev->dev, "cannot remap I/O memory space\n");
 		ret = -ENXIO;
-		goto error;
+		goto free;
 	}
 
 	if (netdev->mem_end) {
@@ -1097,7 +1097,7 @@ static int ethoc_probe(struct platform_d
 		if (!priv->membase) {
 			dev_err(&pdev->dev, "cannot remap memory space\n");
 			ret = -ENXIO;
-			goto error;
+			goto free;
 		}
 	} else {
 		/* Allocate buffer memory */
@@ -1108,7 +1108,7 @@ static int ethoc_probe(struct platform_d
 			dev_err(&pdev->dev, "cannot allocate %dB buffer\n",
 				buffer_size);
 			ret = -ENOMEM;
-			goto error;
+			goto free;
 		}
 		netdev->mem_end = netdev->mem_start + buffer_size;
 		priv->dma_alloc = buffer_size;
@@ -1122,7 +1122,7 @@ static int ethoc_probe(struct platform_d
 		128, (netdev->mem_end - netdev->mem_start + 1) / ETHOC_BUFSIZ);
 	if (num_bd < 4) {
 		ret = -ENODEV;
-		goto error;
+		goto free;
 	}
 	priv->num_bd = num_bd;
 	/* num_tx must be a power of two */
@@ -1135,7 +1135,7 @@ static int ethoc_probe(struct platform_d
 	priv->vma = devm_kzalloc(&pdev->dev, num_bd*sizeof(void *), GFP_KERNEL);
 	if (!priv->vma) {
 		ret = -ENOMEM;
-		goto error;
+		goto free;
 	}
 
 	/* Allow the platform setup code to pass in a MAC address. */
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/hisilicon/hns/hnae.c linux-libre-4.4.223-gnu/drivers/net/ethernet/hisilicon/hns/hnae.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/hisilicon/hns/hnae.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/hisilicon/hns/hnae.c	2020-05-10 04:26:37.000000000 -0400
@@ -331,8 +331,10 @@ struct hnae_handle *hnae_get_handle(stru
 		return ERR_PTR(-ENODEV);
 
 	handle = dev->ops->get_handle(dev, port_id);
-	if (IS_ERR(handle))
+	if (IS_ERR(handle)) {
+		put_device(&dev->cls_dev);
 		return handle;
+	}
 
 	handle->dev = dev;
 	handle->owner_dev = owner_dev;
@@ -355,6 +357,8 @@ out_when_init_queue:
 	for (j = i - 1; j >= 0; j--)
 		hnae_fini_queue(handle->qs[j]);
 
+	put_device(&dev->cls_dev);
+
 	return ERR_PTR(-ENOMEM);
 }
 EXPORT_SYMBOL(hnae_get_handle);
@@ -376,6 +380,8 @@ void hnae_put_handle(struct hnae_handle
 		dev->ops->put_handle(h);
 
 	module_put(dev->owner);
+
+	put_device(&dev->cls_dev);
 }
 EXPORT_SYMBOL(hnae_put_handle);
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/ibm/ehea/ehea_main.c linux-libre-4.4.223-gnu/drivers/net/ethernet/ibm/ehea/ehea_main.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/ibm/ehea/ehea_main.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/ibm/ehea/ehea_main.c	2020-05-10 04:26:37.000000000 -0400
@@ -1169,16 +1169,15 @@ static void ehea_parse_eqe(struct ehea_a
 	ec = EHEA_BMASK_GET(NEQE_EVENT_CODE, eqe);
 	portnum = EHEA_BMASK_GET(NEQE_PORTNUM, eqe);
 	port = ehea_get_port(adapter, portnum);
+	if (!port) {
+		netdev_err(NULL, "unknown portnum %x\n", portnum);
+		return;
+	}
 	dev = port->netdev;
 
 	switch (ec) {
 	case EHEA_EC_PORTSTATE_CHG:	/* port state change */
 
-		if (!port) {
-			netdev_err(dev, "unknown portnum %x\n", portnum);
-			break;
-		}
-
 		if (EHEA_BMASK_GET(NEQE_PORT_UP, eqe)) {
 			if (!netif_carrier_ok(dev)) {
 				ret = ehea_sense_port_attr(port);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/intel/i40e/i40e_hmc.c linux-libre-4.4.223-gnu/drivers/net/ethernet/intel/i40e/i40e_hmc.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/intel/i40e/i40e_hmc.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/intel/i40e/i40e_hmc.c	2020-05-10 04:26:37.000000000 -0400
@@ -49,7 +49,7 @@ i40e_status i40e_add_sd_table_entry(stru
 	struct i40e_hmc_sd_entry *sd_entry;
 	bool dma_mem_alloc_done = false;
 	struct i40e_dma_mem mem;
-	i40e_status ret_code;
+	i40e_status ret_code = I40E_SUCCESS;
 	u64 alloc_len;
 
 	if (NULL == hmc_info->sd_table.sd_entry) {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/marvell/mv643xx_eth.c linux-libre-4.4.223-gnu/drivers/net/ethernet/marvell/mv643xx_eth.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/marvell/mv643xx_eth.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/marvell/mv643xx_eth.c	2020-05-10 04:26:37.000000000 -0400
@@ -762,10 +762,10 @@ txq_put_data_tso(struct net_device *dev,
 
 	if (length <= 8 && (uintptr_t)data & 0x7) {
 		/* Copy unaligned small data fragment to TSO header data area */
-		memcpy(txq->tso_hdrs + txq->tx_curr_desc * TSO_HEADER_SIZE,
+		memcpy(txq->tso_hdrs + tx_index * TSO_HEADER_SIZE,
 		       data, length);
 		desc->buf_ptr = txq->tso_hdrs_dma
-			+ txq->tx_curr_desc * TSO_HEADER_SIZE;
+			+ tx_index * TSO_HEADER_SIZE;
 	} else {
 		/* Alignment is okay, map buffer and hand off to hardware */
 		txq->tx_desc_mapping[tx_index] = DESC_DMA_MAP_SINGLE;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/marvell/mvneta.c linux-libre-4.4.223-gnu/drivers/net/ethernet/marvell/mvneta.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/marvell/mvneta.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/marvell/mvneta.c	2020-05-10 04:26:37.000000000 -0400
@@ -3058,26 +3058,25 @@ static void mvneta_ethtool_update_stats(
 	const struct mvneta_statistic *s;
 	void __iomem *base = pp->base;
 	u32 high, low, val;
+	u64 val64;
 	int i;
 
 	for (i = 0, s = mvneta_statistics;
 	     s < mvneta_statistics + ARRAY_SIZE(mvneta_statistics);
 	     s++, i++) {
-		val = 0;
-
 		switch (s->type) {
 		case T_REG_32:
 			val = readl_relaxed(base + s->offset);
+			pp->ethtool_stats[i] += val;
 			break;
 		case T_REG_64:
 			/* Docs say to read low 32-bit then high */
 			low = readl_relaxed(base + s->offset);
 			high = readl_relaxed(base + s->offset + 4);
-			val = (u64)high << 32 | low;
+			val64 = (u64)high << 32 | low;
+			pp->ethtool_stats[i] += val64;
 			break;
 		}
-
-		pp->ethtool_stats[i] += val;
 	}
 }
 
@@ -3406,7 +3405,7 @@ static int mvneta_probe(struct platform_
 	dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
 	dev->hw_features |= dev->features;
 	dev->vlan_features |= dev->features;
-	dev->priv_flags |= IFF_UNICAST_FLT | IFF_LIVE_ADDR_CHANGE;
+	dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
 	dev->gso_max_segs = MVNETA_MAX_TSO_SEGS;
 
 	err = register_netdev(dev);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/marvell/mvpp2.c linux-libre-4.4.223-gnu/drivers/net/ethernet/marvell/mvpp2.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/marvell/mvpp2.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/marvell/mvpp2.c	2020-05-10 04:26:37.000000000 -0400
@@ -3305,7 +3305,7 @@ static void mvpp2_cls_init(struct mvpp2
 	mvpp2_write(priv, MVPP2_CLS_MODE_REG, MVPP2_CLS_MODE_ACTIVE_MASK);
 
 	/* Clear classifier flow table */
-	memset(&fe.data, 0, MVPP2_CLS_FLOWS_TBL_DATA_WORDS);
+	memset(&fe.data, 0, sizeof(fe.data));
 	for (index = 0; index < MVPP2_CLS_FLOWS_TBL_SIZE; index++) {
 		fe.index = index;
 		mvpp2_cls_flow_write(priv, &fe);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx4/catas.c linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx4/catas.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx4/catas.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx4/catas.c	2020-05-10 04:26:37.000000000 -0400
@@ -182,10 +182,17 @@ void mlx4_enter_error_state(struct mlx4_
 		err = mlx4_reset_slave(dev);
 	else
 		err = mlx4_reset_master(dev);
-	BUG_ON(err != 0);
 
+	if (!err) {
+		mlx4_err(dev, "device was reset successfully\n");
+	} else {
+		/* EEH could have disabled the PCI channel during reset. That's
+		 * recoverable and the PCI error flow will handle it.
+		 */
+		if (!pci_channel_offline(dev->persist->pdev))
+			BUG_ON(1);
+	}
 	dev->persist->state |= MLX4_DEVICE_STATE_INTERNAL_ERROR;
-	mlx4_err(dev, "device was reset successfully\n");
 	mutex_unlock(&persist->device_state_mutex);
 
 	/* At that step HW was already reset, now notify clients */
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx4/cmd.c linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx4/cmd.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx4/cmd.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx4/cmd.c	2020-05-10 04:26:37.000000000 -0400
@@ -2451,6 +2451,7 @@ err_comm_admin:
 	kfree(priv->mfunc.master.slave_state);
 err_comm:
 	iounmap(priv->mfunc.comm);
+	priv->mfunc.comm = NULL;
 err_vhcr:
 	dma_free_coherent(&dev->persist->pdev->dev, PAGE_SIZE,
 			  priv->mfunc.vhcr,
@@ -2518,6 +2519,13 @@ void mlx4_report_internal_err_comm_event
 	int slave;
 	u32 slave_read;
 
+	/* If the comm channel has not yet been initialized,
+	 * skip reporting the internal error event to all
+	 * the communication channels.
+	 */
+	if (!priv->mfunc.comm)
+		return;
+
 	/* Report an internal error event to all
 	 * communication channels.
 	 */
@@ -2552,6 +2560,7 @@ void mlx4_multi_func_cleanup(struct mlx4
 	}
 
 	iounmap(priv->mfunc.comm);
+	priv->mfunc.comm = NULL;
 }
 
 void mlx4_cmd_cleanup(struct mlx4_dev *dev, int cleanup_mask)
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx4/en_netdev.c linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx4/en_netdev.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx4/en_netdev.c	2020-05-10 04:26:37.000000000 -0400
@@ -424,14 +424,18 @@ static int mlx4_en_vlan_rx_add_vid(struc
 	mutex_lock(&mdev->state_lock);
 	if (mdev->device_up && priv->port_up) {
 		err = mlx4_SET_VLAN_FLTR(mdev->dev, priv);
-		if (err)
+		if (err) {
 			en_err(priv, "Failed configuring VLAN filter\n");
+			goto out;
+		}
 	}
-	if (mlx4_register_vlan(mdev->dev, priv->port, vid, &idx))
-		en_dbg(HW, priv, "failed adding vlan %d\n", vid);
-	mutex_unlock(&mdev->state_lock);
+	err = mlx4_register_vlan(mdev->dev, priv->port, vid, &idx);
+	if (err)
+		en_dbg(HW, priv, "Failed adding vlan %d\n", vid);
 
-	return 0;
+out:
+	mutex_unlock(&mdev->state_lock);
+	return err;
 }
 
 static int mlx4_en_vlan_rx_kill_vid(struct net_device *dev,
@@ -439,7 +443,7 @@ static int mlx4_en_vlan_rx_kill_vid(stru
 {
 	struct mlx4_en_priv *priv = netdev_priv(dev);
 	struct mlx4_en_dev *mdev = priv->mdev;
-	int err;
+	int err = 0;
 
 	en_dbg(HW, priv, "Killing VID:%d\n", vid);
 
@@ -456,7 +460,7 @@ static int mlx4_en_vlan_rx_kill_vid(stru
 	}
 	mutex_unlock(&mdev->state_lock);
 
-	return 0;
+	return err;
 }
 
 static void mlx4_en_u64_to_mac(unsigned char dst_mac[ETH_ALEN + 2], u64 src_mac)
@@ -1716,6 +1720,16 @@ int mlx4_en_start_port(struct net_device
 		vxlan_get_rx_port(dev);
 #endif
 	priv->port_up = true;
+
+	/* Process all completions if exist to prevent
+	 * the queues freezing if they are full
+	 */
+	for (i = 0; i < priv->rx_ring_num; i++) {
+		local_bh_disable();
+		napi_schedule(&priv->rx_cq[i]->napi);
+		local_bh_enable();
+	}
+
 	netif_tx_start_all_queues(dev);
 	netif_device_attach(dev);
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx4/en_port.c linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx4/en_port.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx4/en_port.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx4/en_port.c	2020-05-10 04:26:37.000000000 -0400
@@ -164,7 +164,7 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_e
 		return PTR_ERR(mailbox);
 	err = mlx4_cmd_box(mdev->dev, 0, mailbox->dma, in_mod, 0,
 			   MLX4_CMD_DUMP_ETH_STATS, MLX4_CMD_TIME_CLASS_B,
-			   MLX4_CMD_WRAPPED);
+			   MLX4_CMD_NATIVE);
 	if (err)
 		goto out;
 
@@ -325,7 +325,7 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_e
 		err = mlx4_cmd_box(mdev->dev, 0, mailbox->dma,
 				   in_mod | MLX4_DUMP_ETH_STATS_FLOW_CONTROL,
 				   0, MLX4_CMD_DUMP_ETH_STATS,
-				   MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED);
+				   MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
 		if (err)
 			goto out;
 	}
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx4/fw.c linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx4/fw.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx4/fw.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx4/fw.c	2020-05-10 04:26:37.000000000 -0400
@@ -610,8 +610,7 @@ int mlx4_QUERY_FUNC_CAP(struct mlx4_dev
 		MLX4_GET(func_cap->phys_port_id, outbox,
 			 QUERY_FUNC_CAP_PHYS_PORT_ID);
 
-	MLX4_GET(field, outbox, QUERY_FUNC_CAP_FLAGS0_OFFSET);
-	func_cap->flags |= (field & QUERY_FUNC_CAP_PHV_BIT);
+	MLX4_GET(func_cap->flags0, outbox, QUERY_FUNC_CAP_FLAGS0_OFFSET);
 
 	/* All other resources are allocated by the master, but we still report
 	 * 'num' and 'reserved' capabilities as follows:
@@ -2840,7 +2839,7 @@ int get_phv_bit(struct mlx4_dev *dev, u8
 	memset(&func_cap, 0, sizeof(func_cap));
 	err = mlx4_QUERY_FUNC_CAP(dev, port, &func_cap);
 	if (!err)
-		*phv = func_cap.flags & QUERY_FUNC_CAP_PHV_BIT;
+		*phv = func_cap.flags0 & QUERY_FUNC_CAP_PHV_BIT;
 	return err;
 }
 EXPORT_SYMBOL(get_phv_bit);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx4/fw.h linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx4/fw.h
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx4/fw.h	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx4/fw.h	2020-05-10 04:26:37.000000000 -0400
@@ -150,7 +150,7 @@ struct mlx4_func_cap {
 	u32	qp1_proxy_qpn;
 	u32	reserved_lkey;
 	u8	physical_port;
-	u8	port_flags;
+	u8	flags0;
 	u8	flags1;
 	u64	phys_port_id;
 	u32	extra_flags;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx4/intf.c linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx4/intf.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx4/intf.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx4/intf.c	2020-05-10 04:26:37.000000000 -0400
@@ -217,6 +217,9 @@ void mlx4_unregister_device(struct mlx4_
 	struct mlx4_priv *priv = mlx4_priv(dev);
 	struct mlx4_interface *intf;
 
+	if (!(dev->persist->interface_state & MLX4_INTERFACE_STATE_UP))
+		return;
+
 	mlx4_stop_catas_poll(dev);
 	if (dev->persist->interface_state & MLX4_INTERFACE_STATE_DELETION &&
 	    mlx4_is_slave(dev)) {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx4/main.c linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx4/main.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx4/main.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx4/main.c	2020-05-10 04:26:37.000000000 -0400
@@ -3854,45 +3854,53 @@ static pci_ers_result_t mlx4_pci_slot_re
 {
 	struct mlx4_dev_persistent *persist = pci_get_drvdata(pdev);
 	struct mlx4_dev	 *dev  = persist->dev;
-	struct mlx4_priv *priv = mlx4_priv(dev);
-	int               ret;
-	int nvfs[MLX4_MAX_PORTS + 1] = {0, 0, 0};
-	int total_vfs;
+	int err;
 
 	mlx4_err(dev, "mlx4_pci_slot_reset was called\n");
-	ret = pci_enable_device(pdev);
-	if (ret) {
-		mlx4_err(dev, "Can not re-enable device, ret=%d\n", ret);
+	err = pci_enable_device(pdev);
+	if (err) {
+		mlx4_err(dev, "Can not re-enable device, err=%d\n", err);
 		return PCI_ERS_RESULT_DISCONNECT;
 	}
 
 	pci_set_master(pdev);
 	pci_restore_state(pdev);
 	pci_save_state(pdev);
+	return PCI_ERS_RESULT_RECOVERED;
+}
 
+static void mlx4_pci_resume(struct pci_dev *pdev)
+{
+	struct mlx4_dev_persistent *persist = pci_get_drvdata(pdev);
+	struct mlx4_dev	 *dev  = persist->dev;
+	struct mlx4_priv *priv = mlx4_priv(dev);
+	int nvfs[MLX4_MAX_PORTS + 1] = {0, 0, 0};
+	int total_vfs;
+	int err;
+
+	mlx4_err(dev, "%s was called\n", __func__);
 	total_vfs = dev->persist->num_vfs;
 	memcpy(nvfs, dev->persist->nvfs, sizeof(dev->persist->nvfs));
 
 	mutex_lock(&persist->interface_state_mutex);
 	if (!(persist->interface_state & MLX4_INTERFACE_STATE_UP)) {
-		ret = mlx4_load_one(pdev, priv->pci_dev_data, total_vfs, nvfs,
+		err = mlx4_load_one(pdev, priv->pci_dev_data, total_vfs, nvfs,
 				    priv, 1);
-		if (ret) {
-			mlx4_err(dev, "%s: mlx4_load_one failed, ret=%d\n",
-				 __func__,  ret);
+		if (err) {
+			mlx4_err(dev, "%s: mlx4_load_one failed, err=%d\n",
+				 __func__,  err);
 			goto end;
 		}
 
-		ret = restore_current_port_types(dev, dev->persist->
+		err = restore_current_port_types(dev, dev->persist->
 						 curr_port_type, dev->persist->
 						 curr_port_poss_type);
-		if (ret)
-			mlx4_err(dev, "could not restore original port types (%d)\n", ret);
+		if (err)
+			mlx4_err(dev, "could not restore original port types (%d)\n", err);
 	}
 end:
 	mutex_unlock(&persist->interface_state_mutex);
 
-	return ret ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED;
 }
 
 static void mlx4_shutdown(struct pci_dev *pdev)
@@ -3909,6 +3917,7 @@ static void mlx4_shutdown(struct pci_dev
 static const struct pci_error_handlers mlx4_err_handler = {
 	.error_detected = mlx4_pci_err_detected,
 	.slot_reset     = mlx4_pci_slot_reset,
+	.resume		= mlx4_pci_resume,
 };
 
 static struct pci_driver mlx4_driver = {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx4/mcg.c linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx4/mcg.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx4/mcg.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx4/mcg.c	2020-05-10 04:26:37.000000000 -0400
@@ -1109,7 +1109,7 @@ int mlx4_qp_attach_common(struct mlx4_de
 	struct mlx4_cmd_mailbox *mailbox;
 	struct mlx4_mgm *mgm;
 	u32 members_count;
-	int index, prev;
+	int index = -1, prev;
 	int link = 0;
 	int i;
 	int err;
@@ -1188,7 +1188,7 @@ int mlx4_qp_attach_common(struct mlx4_de
 		goto out;
 
 out:
-	if (prot == MLX4_PROT_ETH) {
+	if (prot == MLX4_PROT_ETH && index != -1) {
 		/* manage the steering entry for promisc mode */
 		if (new_entry)
 			err = new_steering_entry(dev, port, steer,
@@ -1464,7 +1464,12 @@ EXPORT_SYMBOL_GPL(mlx4_multicast_detach)
 int mlx4_flow_steer_promisc_add(struct mlx4_dev *dev, u8 port,
 				u32 qpn, enum mlx4_net_trans_promisc_mode mode)
 {
-	struct mlx4_net_trans_rule rule;
+	struct mlx4_net_trans_rule rule = {
+		.queue_mode = MLX4_NET_TRANS_Q_FIFO,
+		.exclusive = 0,
+		.allow_loopback = 1,
+	};
+
 	u64 *regid_p;
 
 	switch (mode) {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx4/mlx4.h linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx4/mlx4.h
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx4/mlx4.h	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx4/mlx4.h	2020-05-10 04:26:37.000000000 -0400
@@ -143,9 +143,10 @@ enum mlx4_resource {
 	RES_MTT,
 	RES_MAC,
 	RES_VLAN,
-	RES_EQ,
+	RES_NPORT_ID,
 	RES_COUNTER,
 	RES_FS_RULE,
+	RES_EQ,
 	MLX4_NUM_OF_RESOURCE_TYPE
 };
 
@@ -1312,8 +1313,6 @@ int mlx4_SET_VLAN_FLTR_wrapper(struct ml
 			       struct mlx4_cmd_info *cmd);
 int mlx4_common_set_vlan_fltr(struct mlx4_dev *dev, int function,
 				     int port, void *buf);
-int mlx4_common_dump_eth_stats(struct mlx4_dev *dev, int slave, u32 in_mod,
-				struct mlx4_cmd_mailbox *outbox);
 int mlx4_DUMP_ETH_STATS_wrapper(struct mlx4_dev *dev, int slave,
 				   struct mlx4_vhcr *vhcr,
 				   struct mlx4_cmd_mailbox *inbox,
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx4/port.c linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx4/port.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx4/port.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx4/port.c	2020-05-10 04:26:37.000000000 -0400
@@ -1155,24 +1155,13 @@ int mlx4_SET_VLAN_FLTR_wrapper(struct ml
 	return err;
 }
 
-int mlx4_common_dump_eth_stats(struct mlx4_dev *dev, int slave,
-			       u32 in_mod, struct mlx4_cmd_mailbox *outbox)
-{
-	return mlx4_cmd_box(dev, 0, outbox->dma, in_mod, 0,
-			    MLX4_CMD_DUMP_ETH_STATS, MLX4_CMD_TIME_CLASS_B,
-			    MLX4_CMD_NATIVE);
-}
-
 int mlx4_DUMP_ETH_STATS_wrapper(struct mlx4_dev *dev, int slave,
 				struct mlx4_vhcr *vhcr,
 				struct mlx4_cmd_mailbox *inbox,
 				struct mlx4_cmd_mailbox *outbox,
 				struct mlx4_cmd_info *cmd)
 {
-	if (slave != dev->caps.function)
-		return 0;
-	return mlx4_common_dump_eth_stats(dev, slave,
-					  vhcr->in_modifier, outbox);
+	return 0;
 }
 
 int mlx4_get_slave_from_roce_gid(struct mlx4_dev *dev, int port, u8 *gid,
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c	2020-05-10 04:26:37.000000000 -0400
@@ -918,11 +918,13 @@ static int handle_existing_counter(struc
 
 	spin_lock_irq(mlx4_tlock(dev));
 	r = find_res(dev, counter_index, RES_COUNTER);
-	if (!r || r->owner != slave)
+	if (!r || r->owner != slave) {
 		ret = -EINVAL;
-	counter = container_of(r, struct res_counter, com);
-	if (!counter->port)
-		counter->port = port;
+	} else {
+		counter = container_of(r, struct res_counter, com);
+		if (!counter->port)
+			counter->port = port;
+	}
 
 	spin_unlock_irq(mlx4_tlock(dev));
 	return ret;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx5/core/cmd.c linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx5/core/cmd.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx5/core/cmd.c	2020-05-10 04:26:37.000000000 -0400
@@ -634,11 +634,36 @@ static void free_msg(struct mlx5_core_de
 static void mlx5_free_cmd_msg(struct mlx5_core_dev *dev,
 			      struct mlx5_cmd_msg *msg);
 
+static u16 msg_to_opcode(struct mlx5_cmd_msg *in)
+{
+	struct mlx5_inbox_hdr *hdr = (struct mlx5_inbox_hdr *)(in->first.data);
+
+	return be16_to_cpu(hdr->opcode);
+}
+
+static void cb_timeout_handler(struct work_struct *work)
+{
+	struct delayed_work *dwork = container_of(work, struct delayed_work,
+						  work);
+	struct mlx5_cmd_work_ent *ent = container_of(dwork,
+						     struct mlx5_cmd_work_ent,
+						     cb_timeout_work);
+	struct mlx5_core_dev *dev = container_of(ent->cmd, struct mlx5_core_dev,
+						 cmd);
+
+	ent->ret = -ETIMEDOUT;
+	mlx5_core_warn(dev, "%s(0x%x) timeout. Will cause a leak of a command resource\n",
+		       mlx5_command_str(msg_to_opcode(ent->in)),
+		       msg_to_opcode(ent->in));
+	mlx5_cmd_comp_handler(dev, 1UL << ent->idx);
+}
+
 static void cmd_work_handler(struct work_struct *work)
 {
 	struct mlx5_cmd_work_ent *ent = container_of(work, struct mlx5_cmd_work_ent, work);
 	struct mlx5_cmd *cmd = ent->cmd;
 	struct mlx5_core_dev *dev = container_of(cmd, struct mlx5_core_dev, cmd);
+	unsigned long cb_timeout = msecs_to_jiffies(MLX5_CMD_TIMEOUT_MSEC);
 	struct mlx5_cmd_layout *lay;
 	struct semaphore *sem;
 	unsigned long flags;
@@ -691,6 +716,9 @@ static void cmd_work_handler(struct work
 	ent->ts1 = ktime_get_ns();
 	cmd_mode = cmd->mode;
 
+	if (ent->callback)
+		schedule_delayed_work(&ent->cb_timeout_work, cb_timeout);
+
 	/* ring doorbell after the descriptor is valid */
 	mlx5_core_dbg(dev, "writing 0x%x to command doorbell\n", 1 << ent->idx);
 	wmb();
@@ -735,13 +763,6 @@ static const char *deliv_status_to_str(u
 	}
 }
 
-static u16 msg_to_opcode(struct mlx5_cmd_msg *in)
-{
-	struct mlx5_inbox_hdr *hdr = (struct mlx5_inbox_hdr *)(in->first.data);
-
-	return be16_to_cpu(hdr->opcode);
-}
-
 static int wait_func(struct mlx5_core_dev *dev, struct mlx5_cmd_work_ent *ent)
 {
 	unsigned long timeout = msecs_to_jiffies(MLX5_CMD_TIMEOUT_MSEC);
@@ -750,13 +771,13 @@ static int wait_func(struct mlx5_core_de
 
 	if (cmd->mode == CMD_MODE_POLLING) {
 		wait_for_completion(&ent->done);
-		err = ent->ret;
-	} else {
-		if (!wait_for_completion_timeout(&ent->done, timeout))
-			err = -ETIMEDOUT;
-		else
-			err = 0;
+	} else if (!wait_for_completion_timeout(&ent->done, timeout)) {
+		ent->ret = -ETIMEDOUT;
+		mlx5_cmd_comp_handler(dev, 1UL << ent->idx);
 	}
+
+	err = ent->ret;
+
 	if (err == -ETIMEDOUT) {
 		mlx5_core_warn(dev, "%s(0x%x) timeout. Will cause a leak of a command resource\n",
 			       mlx5_command_str(msg_to_opcode(ent->in)),
@@ -808,6 +829,7 @@ static int mlx5_cmd_invoke(struct mlx5_c
 	if (!callback)
 		init_completion(&ent->done);
 
+	INIT_DELAYED_WORK(&ent->cb_timeout_work, cb_timeout_handler);
 	INIT_WORK(&ent->work, cmd_work_handler);
 	if (page_queue) {
 		cmd_work_handler(&ent->work);
@@ -817,28 +839,26 @@ static int mlx5_cmd_invoke(struct mlx5_c
 		goto out_free;
 	}
 
-	if (!callback) {
-		err = wait_func(dev, ent);
-		if (err == -ETIMEDOUT)
-			goto out;
+	if (callback)
+		goto out;
 
-		ds = ent->ts2 - ent->ts1;
-		op = be16_to_cpu(((struct mlx5_inbox_hdr *)in->first.data)->opcode);
-		if (op < ARRAY_SIZE(cmd->stats)) {
-			stats = &cmd->stats[op];
-			spin_lock_irq(&stats->lock);
-			stats->sum += ds;
-			++stats->n;
-			spin_unlock_irq(&stats->lock);
-		}
-		mlx5_core_dbg_mask(dev, 1 << MLX5_CMD_TIME,
-				   "fw exec time for %s is %lld nsec\n",
-				   mlx5_command_str(op), ds);
-		*status = ent->status;
-		free_cmd(ent);
-	}
+	err = wait_func(dev, ent);
+	if (err == -ETIMEDOUT)
+		goto out_free;
 
-	return err;
+	ds = ent->ts2 - ent->ts1;
+	op = be16_to_cpu(((struct mlx5_inbox_hdr *)in->first.data)->opcode);
+	if (op < ARRAY_SIZE(cmd->stats)) {
+		stats = &cmd->stats[op];
+		spin_lock_irq(&stats->lock);
+		stats->sum += ds;
+		++stats->n;
+		spin_unlock_irq(&stats->lock);
+	}
+	mlx5_core_dbg_mask(dev, 1 << MLX5_CMD_TIME,
+			   "fw exec time for %s is %lld nsec\n",
+			   mlx5_command_str(op), ds);
+	*status = ent->status;
 
 out_free:
 	free_cmd(ent);
@@ -1230,41 +1250,30 @@ err_dbg:
 	return err;
 }
 
-void mlx5_cmd_use_events(struct mlx5_core_dev *dev)
+static void mlx5_cmd_change_mod(struct mlx5_core_dev *dev, int mode)
 {
 	struct mlx5_cmd *cmd = &dev->cmd;
 	int i;
 
 	for (i = 0; i < cmd->max_reg_cmds; i++)
 		down(&cmd->sem);
-
 	down(&cmd->pages_sem);
 
-	flush_workqueue(cmd->wq);
-
-	cmd->mode = CMD_MODE_EVENTS;
+	cmd->mode = mode;
 
 	up(&cmd->pages_sem);
 	for (i = 0; i < cmd->max_reg_cmds; i++)
 		up(&cmd->sem);
 }
 
-void mlx5_cmd_use_polling(struct mlx5_core_dev *dev)
+void mlx5_cmd_use_events(struct mlx5_core_dev *dev)
 {
-	struct mlx5_cmd *cmd = &dev->cmd;
-	int i;
-
-	for (i = 0; i < cmd->max_reg_cmds; i++)
-		down(&cmd->sem);
-
-	down(&cmd->pages_sem);
-
-	flush_workqueue(cmd->wq);
-	cmd->mode = CMD_MODE_POLLING;
+	mlx5_cmd_change_mod(dev, CMD_MODE_EVENTS);
+}
 
-	up(&cmd->pages_sem);
-	for (i = 0; i < cmd->max_reg_cmds; i++)
-		up(&cmd->sem);
+void mlx5_cmd_use_polling(struct mlx5_core_dev *dev)
+{
+	mlx5_cmd_change_mod(dev, CMD_MODE_POLLING);
 }
 
 static void free_msg(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *msg)
@@ -1300,6 +1309,8 @@ void mlx5_cmd_comp_handler(struct mlx5_c
 			struct semaphore *sem;
 
 			ent = cmd->ent_arr[i];
+			if (ent->callback)
+				cancel_delayed_work(&ent->cb_timeout_work);
 			if (ent->page_queue)
 				sem = &cmd->pages_sem;
 			else
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c	2020-05-10 04:26:37.000000000 -0400
@@ -138,10 +138,10 @@ static const struct {
 	[MLX5E_100BASE_TX]   = {
 		.speed      = 100,
 	},
-	[MLX5E_100BASE_T]    = {
-		.supported  = SUPPORTED_100baseT_Full,
-		.advertised = ADVERTISED_100baseT_Full,
-		.speed      = 100,
+	[MLX5E_1000BASE_T]    = {
+		.supported  = SUPPORTED_1000baseT_Full,
+		.advertised = ADVERTISED_1000baseT_Full,
+		.speed      = 1000,
 	},
 	[MLX5E_10GBASE_T]    = {
 		.supported  = SUPPORTED_10000baseT_Full,
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx5/core/en.h linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx5/core/en.h
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx5/core/en.h	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx5/core/en.h	2020-05-10 04:26:37.000000000 -0400
@@ -543,7 +543,7 @@ enum mlx5e_link_mode {
 	MLX5E_100GBASE_KR4	 = 22,
 	MLX5E_100GBASE_LR4	 = 23,
 	MLX5E_100BASE_TX	 = 24,
-	MLX5E_100BASE_T		 = 25,
+	MLX5E_1000BASE_T	 = 25,
 	MLX5E_10GBASE_T		 = 26,
 	MLX5E_25GBASE_CR	 = 27,
 	MLX5E_25GBASE_KR	 = 28,
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c	2020-05-10 04:26:37.000000000 -0400
@@ -124,7 +124,7 @@ static inline u16 mlx5e_get_inline_hdr_s
 	 * headers and occur before the data gather.
 	 * Therefore these headers must be copied into the WQE
 	 */
-#define MLX5E_MIN_INLINE ETH_HLEN
+#define MLX5E_MIN_INLINE (ETH_HLEN + VLAN_HLEN)
 
 	if (bf) {
 		u16 ihs = skb_headlen(skb);
@@ -136,7 +136,7 @@ static inline u16 mlx5e_get_inline_hdr_s
 			return skb_headlen(skb);
 	}
 
-	return MLX5E_MIN_INLINE;
+	return max(skb_network_offset(skb), MLX5E_MIN_INLINE);
 }
 
 static inline void mlx5e_insert_vlan(void *start, struct sk_buff *skb, u16 ihs)
@@ -290,7 +290,8 @@ static netdev_tx_t mlx5e_sq_xmit(struct
 	while ((sq->pc & wq->sz_m1) > sq->edge)
 		mlx5e_send_nop(sq, false);
 
-	sq->bf_budget = bf ? sq->bf_budget - 1 : 0;
+	if (bf)
+		sq->bf_budget--;
 
 	sq->stats.packets++;
 	return NETDEV_TX_OK;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx5/core/health.c linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx5/core/health.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx5/core/health.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx5/core/health.c	2020-05-10 04:26:37.000000000 -0400
@@ -108,15 +108,21 @@ static int in_fatal(struct mlx5_core_dev
 
 void mlx5_enter_error_state(struct mlx5_core_dev *dev)
 {
+	mutex_lock(&dev->intf_state_mutex);
 	if (dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR)
-		return;
+		goto unlock;
 
 	mlx5_core_err(dev, "start\n");
-	if (pci_channel_offline(dev->pdev) || in_fatal(dev))
+	if (pci_channel_offline(dev->pdev) || in_fatal(dev)) {
 		dev->state = MLX5_DEVICE_STATE_INTERNAL_ERROR;
+		trigger_cmd_completions(dev);
+	}
 
 	mlx5_core_event(dev, MLX5_DEV_EVENT_SYS_ERROR, 0);
 	mlx5_core_err(dev, "end\n");
+
+unlock:
+	mutex_unlock(&dev->intf_state_mutex);
 }
 
 static void mlx5_handle_bad_state(struct mlx5_core_dev *dev)
@@ -245,7 +251,6 @@ static void poll_health(unsigned long da
 	u32 count;
 
 	if (dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) {
-		trigger_cmd_completions(dev);
 		mod_timer(&health->timer, get_next_poll_jiffies());
 		return;
 	}
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx5/core/main.c linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx5/core/main.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx5/core/main.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx5/core/main.c	2020-05-10 04:26:37.000000000 -0400
@@ -1276,15 +1276,43 @@ static pci_ers_result_t mlx5_pci_err_det
 	dev_info(&pdev->dev, "%s was called\n", __func__);
 	mlx5_enter_error_state(dev);
 	mlx5_unload_one(dev, priv);
+	pci_save_state(pdev);
 	mlx5_pci_disable_device(dev);
 	return state == pci_channel_io_perm_failure ?
 		PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_NEED_RESET;
 }
 
+/* wait for the device to show vital signs by waiting
+ * for the health counter to start counting.
+ */
+static int wait_vital(struct pci_dev *pdev)
+{
+	struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
+	struct mlx5_core_health *health = &dev->priv.health;
+	const int niter = 100;
+	u32 last_count = 0;
+	u32 count;
+	int i;
+
+	for (i = 0; i < niter; i++) {
+		count = ioread32be(health->health_counter);
+		if (count && count != 0xffffffff) {
+			if (last_count && last_count != count) {
+				dev_info(&pdev->dev, "Counter value 0x%x after %d iterations\n", count, i);
+				return 0;
+			}
+			last_count = count;
+		}
+		msleep(50);
+	}
+
+	return -ETIMEDOUT;
+}
+
 static pci_ers_result_t mlx5_pci_slot_reset(struct pci_dev *pdev)
 {
 	struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
-	int err = 0;
+	int err;
 
 	dev_info(&pdev->dev, "%s was called\n", __func__);
 
@@ -1294,11 +1322,16 @@ static pci_ers_result_t mlx5_pci_slot_re
 			, __func__, err);
 		return PCI_ERS_RESULT_DISCONNECT;
 	}
+
 	pci_set_master(pdev);
-	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
 
-	return err ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED;
+	if (wait_vital(pdev)) {
+		dev_err(&pdev->dev, "%s: wait_vital timed out\n", __func__);
+		return PCI_ERS_RESULT_DISCONNECT;
+	}
+
+	return PCI_ERS_RESULT_RECOVERED;
 }
 
 void mlx5_disable_device(struct mlx5_core_dev *dev)
@@ -1306,48 +1339,6 @@ void mlx5_disable_device(struct mlx5_cor
 	mlx5_pci_err_detected(dev->pdev, 0);
 }
 
-/* wait for the device to show vital signs. For now we check
- * that we can read the device ID and that the health buffer
- * shows a non zero value which is different than 0xffffffff
- */
-static void wait_vital(struct pci_dev *pdev)
-{
-	struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
-	struct mlx5_core_health *health = &dev->priv.health;
-	const int niter = 100;
-	u32 count;
-	u16 did;
-	int i;
-
-	/* Wait for firmware to be ready after reset */
-	msleep(1000);
-	for (i = 0; i < niter; i++) {
-		if (pci_read_config_word(pdev, 2, &did)) {
-			dev_warn(&pdev->dev, "failed reading config word\n");
-			break;
-		}
-		if (did == pdev->device) {
-			dev_info(&pdev->dev, "device ID correctly read after %d iterations\n", i);
-			break;
-		}
-		msleep(50);
-	}
-	if (i == niter)
-		dev_warn(&pdev->dev, "%s-%d: could not read device ID\n", __func__, __LINE__);
-
-	for (i = 0; i < niter; i++) {
-		count = ioread32be(health->health_counter);
-		if (count && count != 0xffffffff) {
-			dev_info(&pdev->dev, "Counter value 0x%x after %d iterations\n", count, i);
-			break;
-		}
-		msleep(50);
-	}
-
-	if (i == niter)
-		dev_warn(&pdev->dev, "%s-%d: could not read device ID\n", __func__, __LINE__);
-}
-
 static void mlx5_pci_resume(struct pci_dev *pdev)
 {
 	struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
@@ -1356,9 +1347,6 @@ static void mlx5_pci_resume(struct pci_d
 
 	dev_info(&pdev->dev, "%s was called\n", __func__);
 
-	pci_save_state(pdev);
-	wait_vital(pdev);
-
 	err = mlx5_load_one(dev, priv);
 	if (err)
 		dev_err(&pdev->dev, "%s: mlx5_load_one failed with error code: %d\n"
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c	2020-05-10 04:26:37.000000000 -0400
@@ -243,6 +243,7 @@ static void free_4k(struct mlx5_core_dev
 static int alloc_system_page(struct mlx5_core_dev *dev, u16 func_id)
 {
 	struct page *page;
+	u64 zero_addr = 1;
 	u64 addr;
 	int err;
 	int nid = dev_to_node(&dev->pdev->dev);
@@ -252,26 +253,35 @@ static int alloc_system_page(struct mlx5
 		mlx5_core_warn(dev, "failed to allocate page\n");
 		return -ENOMEM;
 	}
+map:
 	addr = dma_map_page(&dev->pdev->dev, page, 0,
 			    PAGE_SIZE, DMA_BIDIRECTIONAL);
 	if (dma_mapping_error(&dev->pdev->dev, addr)) {
 		mlx5_core_warn(dev, "failed dma mapping page\n");
 		err = -ENOMEM;
-		goto out_alloc;
+		goto err_mapping;
 	}
+
+	/* Firmware doesn't support page with physical address 0 */
+	if (addr == 0) {
+		zero_addr = addr;
+		goto map;
+	}
+
 	err = insert_page(dev, addr, page, func_id);
 	if (err) {
 		mlx5_core_err(dev, "failed to track allocated page\n");
-		goto out_mapping;
+		dma_unmap_page(&dev->pdev->dev, addr, PAGE_SIZE,
+			       DMA_BIDIRECTIONAL);
 	}
 
-	return 0;
-
-out_mapping:
-	dma_unmap_page(&dev->pdev->dev, addr, PAGE_SIZE, DMA_BIDIRECTIONAL);
+err_mapping:
+	if (err)
+		__free_page(page);
 
-out_alloc:
-	__free_page(page);
+	if (zero_addr == 0)
+		dma_unmap_page(&dev->pdev->dev, zero_addr, PAGE_SIZE,
+			       DMA_BIDIRECTIONAL);
 
 	return err;
 }
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx5/core/qp.c linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx5/core/qp.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx5/core/qp.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx5/core/qp.c	2020-05-10 04:26:37.000000000 -0400
@@ -393,7 +393,7 @@ int mlx5_core_xrcd_alloc(struct mlx5_cor
 	if (out.hdr.status)
 		err = mlx5_cmd_status_to_err(&out.hdr);
 	else
-		*xrcdn = be32_to_cpu(out.xrcdn);
+		*xrcdn = be32_to_cpu(out.xrcdn) & 0xffffff;
 
 	return err;
 }
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx5/core/wq.c linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx5/core/wq.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlx5/core/wq.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlx5/core/wq.c	2020-05-10 04:26:37.000000000 -0400
@@ -75,14 +75,14 @@ int mlx5_wq_cyc_create(struct mlx5_core_
 
 	err = mlx5_db_alloc_node(mdev, &wq_ctrl->db, param->db_numa_node);
 	if (err) {
-		mlx5_core_warn(mdev, "mlx5_db_alloc() failed, %d\n", err);
+		mlx5_core_warn(mdev, "mlx5_db_alloc_node() failed, %d\n", err);
 		return err;
 	}
 
 	err = mlx5_buf_alloc_node(mdev, mlx5_wq_cyc_get_byte_size(wq),
 				  &wq_ctrl->buf, param->buf_numa_node);
 	if (err) {
-		mlx5_core_warn(mdev, "mlx5_buf_alloc() failed, %d\n", err);
+		mlx5_core_warn(mdev, "mlx5_buf_alloc_node() failed, %d\n", err);
 		goto err_db_free;
 	}
 
@@ -111,14 +111,14 @@ int mlx5_cqwq_create(struct mlx5_core_de
 
 	err = mlx5_db_alloc_node(mdev, &wq_ctrl->db, param->db_numa_node);
 	if (err) {
-		mlx5_core_warn(mdev, "mlx5_db_alloc() failed, %d\n", err);
+		mlx5_core_warn(mdev, "mlx5_db_alloc_node() failed, %d\n", err);
 		return err;
 	}
 
 	err = mlx5_buf_alloc_node(mdev, mlx5_cqwq_get_byte_size(wq),
 				  &wq_ctrl->buf, param->buf_numa_node);
 	if (err) {
-		mlx5_core_warn(mdev, "mlx5_buf_alloc() failed, %d\n", err);
+		mlx5_core_warn(mdev, "mlx5_buf_alloc_node() failed, %d\n", err);
 		goto err_db_free;
 	}
 
@@ -148,13 +148,14 @@ int mlx5_wq_ll_create(struct mlx5_core_d
 
 	err = mlx5_db_alloc_node(mdev, &wq_ctrl->db, param->db_numa_node);
 	if (err) {
-		mlx5_core_warn(mdev, "mlx5_db_alloc() failed, %d\n", err);
+		mlx5_core_warn(mdev, "mlx5_db_alloc_node() failed, %d\n", err);
 		return err;
 	}
 
-	err = mlx5_buf_alloc(mdev, mlx5_wq_ll_get_byte_size(wq), &wq_ctrl->buf);
+	err = mlx5_buf_alloc_node(mdev, mlx5_wq_ll_get_byte_size(wq),
+				  &wq_ctrl->buf, param->buf_numa_node);
 	if (err) {
-		mlx5_core_warn(mdev, "mlx5_buf_alloc() failed, %d\n", err);
+		mlx5_core_warn(mdev, "mlx5_buf_alloc_node() failed, %d\n", err);
 		goto err_db_free;
 	}
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlxsw/pci.c linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlxsw/pci.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlxsw/pci.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlxsw/pci.c	2020-05-10 04:26:37.000000000 -0400
@@ -215,7 +215,7 @@ mlxsw_pci_queue_elem_info_producer_get(s
 {
 	int index = q->producer_counter & (q->count - 1);
 
-	if ((q->producer_counter - q->consumer_counter) == q->count)
+	if ((u16) (q->producer_counter - q->consumer_counter) == q->count)
 		return NULL;
 	return mlxsw_pci_queue_elem_info_get(q, index);
 }
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlxsw/port.h linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlxsw/port.h
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlxsw/port.h	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlxsw/port.h	2020-05-10 04:26:37.000000000 -0400
@@ -49,7 +49,7 @@
 #define MLXSW_PORT_MID			0xd000
 
 #define MLXSW_PORT_MAX_PHY_PORTS	0x40
-#define MLXSW_PORT_MAX_PORTS		MLXSW_PORT_MAX_PHY_PORTS
+#define MLXSW_PORT_MAX_PORTS		(MLXSW_PORT_MAX_PHY_PORTS + 1)
 
 #define MLXSW_PORT_DEVID_BITS_OFFSET	10
 #define MLXSW_PORT_PHY_BITS_OFFSET	4
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlxsw/spectrum.c linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlxsw/spectrum.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlxsw/spectrum.c	2020-05-10 04:26:37.000000000 -0400
@@ -399,7 +399,11 @@ static netdev_tx_t mlxsw_sp_port_xmit(st
 	}
 
 	mlxsw_sp_txhdr_construct(skb, &tx_info);
-	len = skb->len;
+	/* TX header is consumed by HW on the way so we shouldn't count its
+	 * bytes as being sent.
+	 */
+	len = skb->len - MLXSW_TXHDR_LEN;
+
 	/* Due to a race we might fail here because of a full queue. In that
 	 * unlikely case we simply drop the packet.
 	 */
@@ -1100,7 +1104,8 @@ static int mlxsw_sp_port_get_settings(st
 
 	cmd->supported = mlxsw_sp_from_ptys_supported_port(eth_proto_cap) |
 			 mlxsw_sp_from_ptys_supported_link(eth_proto_cap) |
-			 SUPPORTED_Pause | SUPPORTED_Asym_Pause;
+			 SUPPORTED_Pause | SUPPORTED_Asym_Pause |
+			 SUPPORTED_Autoneg;
 	cmd->advertising = mlxsw_sp_from_ptys_advert_link(eth_proto_admin);
 	mlxsw_sp_from_ptys_speed_duplex(netif_carrier_ok(dev),
 					eth_proto_oper, cmd);
@@ -1256,7 +1261,7 @@ static int mlxsw_sp_port_create(struct m
 	/* Each packet needs to have a Tx header (metadata) on top all other
 	 * headers.
 	 */
-	dev->hard_header_len += MLXSW_TXHDR_LEN;
+	dev->needed_headroom = MLXSW_TXHDR_LEN;
 
 	err = mlxsw_sp_port_module_check(mlxsw_sp_port, &usable);
 	if (err) {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c	2020-05-10 04:26:37.000000000 -0400
@@ -87,14 +87,14 @@ static int mlxsw_sp_port_stp_state_set(s
 	int err;
 
 	switch (state) {
-	case BR_STATE_DISABLED: /* fall-through */
 	case BR_STATE_FORWARDING:
 		spms_state = MLXSW_REG_SPMS_STATE_FORWARDING;
 		break;
-	case BR_STATE_LISTENING: /* fall-through */
 	case BR_STATE_LEARNING:
 		spms_state = MLXSW_REG_SPMS_STATE_LEARNING;
 		break;
+	case BR_STATE_LISTENING: /* fall-through */
+	case BR_STATE_DISABLED: /* fall-through */
 	case BR_STATE_BLOCKING:
 		spms_state = MLXSW_REG_SPMS_STATE_DISCARDING;
 		break;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlxsw/switchx2.c linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/mellanox/mlxsw/switchx2.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/mellanox/mlxsw/switchx2.c	2020-05-10 04:26:37.000000000 -0400
@@ -993,7 +993,7 @@ static int mlxsw_sx_port_create(struct m
 	/* Each packet needs to have a Tx header (metadata) on top all other
 	 * headers.
 	 */
-	dev->hard_header_len += MLXSW_TXHDR_LEN;
+	dev->needed_headroom = MLXSW_TXHDR_LEN;
 
 	err = mlxsw_sx_port_module_check(mlxsw_sx_port, &usable);
 	if (err) {
@@ -1074,6 +1074,7 @@ err_port_stp_state_set:
 err_port_admin_status_set:
 err_port_mtu_set:
 err_port_speed_set:
+	mlxsw_sx_port_swid_set(mlxsw_sx_port, MLXSW_PORT_SWID_DISABLED_PORT);
 err_port_swid_set:
 err_port_system_port_mapping_set:
 port_not_usable:
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/micrel/ks8842.c linux-libre-4.4.223-gnu/drivers/net/ethernet/micrel/ks8842.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/micrel/ks8842.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/micrel/ks8842.c	2020-05-10 04:26:37.000000000 -0400
@@ -561,8 +561,8 @@ static int __ks8842_start_new_rx_dma(str
 		sg_init_table(sg, 1);
 		sg_dma_address(sg) = dma_map_single(adapter->dev,
 			ctl->skb->data, DMA_BUFFER_SIZE, DMA_FROM_DEVICE);
-		err = dma_mapping_error(adapter->dev, sg_dma_address(sg));
-		if (unlikely(err)) {
+		if (dma_mapping_error(adapter->dev, sg_dma_address(sg))) {
+			err = -ENOMEM;
 			sg_dma_address(sg) = 0;
 			goto out;
 		}
@@ -572,8 +572,10 @@ static int __ks8842_start_new_rx_dma(str
 		ctl->adesc = dmaengine_prep_slave_sg(ctl->chan,
 			sg, 1, DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT);
 
-		if (!ctl->adesc)
+		if (!ctl->adesc) {
+			err = -ENOMEM;
 			goto out;
+		}
 
 		ctl->adesc->callback_param = netdev;
 		ctl->adesc->callback = ks8842_dma_rx_cb;
@@ -584,7 +586,7 @@ static int __ks8842_start_new_rx_dma(str
 		goto out;
 	}
 
-	return err;
+	return 0;
 out:
 	if (sg_dma_address(sg))
 		dma_unmap_single(adapter->dev, sg_dma_address(sg),
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/moxa/moxart_ether.c linux-libre-4.4.223-gnu/drivers/net/ethernet/moxa/moxart_ether.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/moxa/moxart_ether.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/moxa/moxart_ether.c	2020-05-10 04:26:37.000000000 -0400
@@ -460,9 +460,9 @@ static int moxart_mac_probe(struct platf
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	ndev->base_addr = res->start;
 	priv->base = devm_ioremap_resource(p_dev, res);
-	ret = IS_ERR(priv->base);
-	if (ret) {
+	if (IS_ERR(priv->base)) {
 		dev_err(p_dev, "devm_ioremap_resource failed\n");
+		ret = PTR_ERR(priv->base);
 		goto init_fail;
 	}
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/qlogic/qede/qede_main.c linux-libre-4.4.223-gnu/drivers/net/ethernet/qlogic/qede/qede_main.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/qlogic/qede/qede_main.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/qlogic/qede/qede_main.c	2020-05-10 04:26:37.000000000 -0400
@@ -400,7 +400,7 @@ netdev_tx_t qede_start_xmit(struct sk_bu
 	u8 xmit_type;
 	u16 idx;
 	u16 hlen;
-	bool data_split;
+	bool data_split = false;
 
 	/* Get tx-queue context and netdev index */
 	txq_index = skb_get_queue_mapping(skb);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c linux-libre-4.4.223-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c	2020-05-10 04:26:37.000000000 -0400
@@ -2220,7 +2220,7 @@ void qlcnic_83xx_process_rcv_ring_diag(s
 	if (!opcode)
 		return;
 
-	ring = QLCNIC_FETCH_RING_ID(qlcnic_83xx_hndl(sts_data[0]));
+	ring = QLCNIC_FETCH_RING_ID(sts_data[0]);
 	qlcnic_83xx_process_rcv_diag(adapter, ring, sts_data);
 	desc = &sds_ring->desc_head[consumer];
 	desc->status_desc_data[0] = cpu_to_le64(STATUS_OWNER_PHANTOM);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c linux-libre-4.4.223-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c	2020-05-10 04:26:37.000000000 -0400
@@ -1419,6 +1419,7 @@ void qlcnic_83xx_get_minidump_template(s
 	struct qlcnic_fw_dump *fw_dump = &ahw->fw_dump;
 	struct pci_dev *pdev = adapter->pdev;
 	bool extended = false;
+	int ret;
 
 	prev_version = adapter->fw_version;
 	current_version = qlcnic_83xx_get_fw_version(adapter);
@@ -1429,8 +1430,11 @@ void qlcnic_83xx_get_minidump_template(s
 		if (qlcnic_83xx_md_check_extended_dump_capability(adapter))
 			extended = !qlcnic_83xx_extend_md_capab(adapter);
 
-		if (!qlcnic_fw_cmd_get_minidump_temp(adapter))
-			dev_info(&pdev->dev, "Supports FW dump capability\n");
+		ret = qlcnic_fw_cmd_get_minidump_temp(adapter);
+		if (ret)
+			return;
+
+		dev_info(&pdev->dev, "Supports FW dump capability\n");
 
 		/* Once we have minidump template with extended iSCSI dump
 		 * capability, update the minidump capture mask to 0x1f as
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/renesas/ravb_main.c linux-libre-4.4.223-gnu/drivers/net/ethernet/renesas/ravb_main.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/renesas/ravb_main.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/renesas/ravb_main.c	2020-05-10 04:26:37.000000000 -0400
@@ -1528,6 +1528,8 @@ static int ravb_close(struct net_device
 		priv->phydev = NULL;
 	}
 
+	if (priv->chip_id == RCAR_GEN3)
+		free_irq(priv->emac_irq, ndev);
 	free_irq(ndev->irq, ndev);
 
 	napi_disable(&priv->napi[RAVB_NC]);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/sfc/ef10.c linux-libre-4.4.223-gnu/drivers/net/ethernet/sfc/ef10.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/sfc/ef10.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/sfc/ef10.c	2020-05-10 04:26:37.000000000 -0400
@@ -1304,13 +1304,14 @@ static void efx_ef10_get_stat_mask(struc
 	}
 
 #if BITS_PER_LONG == 64
+	BUILD_BUG_ON(BITS_TO_LONGS(EF10_STAT_COUNT) != 2);
 	mask[0] = raw_mask[0];
 	mask[1] = raw_mask[1];
 #else
+	BUILD_BUG_ON(BITS_TO_LONGS(EF10_STAT_COUNT) != 3);
 	mask[0] = raw_mask[0] & 0xffffffff;
 	mask[1] = raw_mask[0] >> 32;
 	mask[2] = raw_mask[1] & 0xffffffff;
-	mask[3] = raw_mask[1] >> 32;
 #endif
 }
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/sfc/efx.c linux-libre-4.4.223-gnu/drivers/net/ethernet/sfc/efx.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/sfc/efx.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/sfc/efx.c	2020-05-10 04:26:37.000000000 -0400
@@ -479,6 +479,9 @@ efx_copy_channel(const struct efx_channe
 	*channel = *old_channel;
 
 	channel->napi_dev = NULL;
+	INIT_HLIST_NODE(&channel->napi_str.napi_hash_node);
+	channel->napi_str.napi_id = 0;
+	channel->napi_str.state = 0;
 	memset(&channel->eventq, 0, sizeof(channel->eventq));
 
 	for (j = 0; j < EFX_TXQ_TYPES; j++) {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c linux-libre-4.4.223-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c	2020-05-10 04:26:37.000000000 -0400
@@ -53,7 +53,17 @@ static int dwmac_generic_probe(struct pl
 			return ret;
 	}
 
-	return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+	if (ret)
+		goto err_exit;
+
+	return 0;
+
+err_exit:
+	if (plat_dat->exit)
+		plat_dat->exit(pdev, plat_dat->bsp_priv);
+
+	return ret;
 }
 
 static const struct of_device_id dwmac_generic_match[] = {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c linux-libre-4.4.223-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c	2020-05-10 04:26:37.000000000 -0400
@@ -600,7 +600,16 @@ static int rk_gmac_probe(struct platform
 	if (ret)
 		return ret;
 
-	return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+	if (ret)
+		goto err_gmac_exit;
+
+	return 0;
+
+err_gmac_exit:
+	rk_gmac_exit(pdev, plat_dat->bsp_priv);
+
+	return ret;
 }
 
 static const struct of_device_id rk_gmac_dwmac_match[] = {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c linux-libre-4.4.223-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c	2020-05-10 04:26:37.000000000 -0400
@@ -365,7 +365,16 @@ static int sti_dwmac_probe(struct platfo
 	if (ret)
 		return ret;
 
-	return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+	if (ret)
+		goto err_dwmac_exit;
+
+	return 0;
+
+err_dwmac_exit:
+	sti_dwmac_exit(pdev, plat_dat->bsp_priv);
+
+	return ret;
 }
 
 static const struct sti_dwmac_of_data stih4xx_dwmac_data = {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/ti/cpsw.c linux-libre-4.4.223-gnu/drivers/net/ethernet/ti/cpsw.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/ti/cpsw.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/ti/cpsw.c	2020-05-10 04:26:37.000000000 -0400
@@ -2060,7 +2060,11 @@ static int cpsw_probe_dt(struct cpsw_pla
 		slave_data->phy_node = of_parse_phandle(slave_node,
 							"phy-handle", 0);
 		parp = of_get_property(slave_node, "phy_id", &lenp);
-		if (of_phy_is_fixed_link(slave_node)) {
+		if (slave_data->phy_node) {
+			dev_dbg(&pdev->dev,
+				"slave[%d] using phy-handle=\"%s\"\n",
+				i, slave_data->phy_node->full_name);
+		} else if (of_phy_is_fixed_link(slave_node)) {
 			struct device_node *phy_node;
 			struct phy_device *phy_dev;
 
@@ -2097,7 +2101,9 @@ static int cpsw_probe_dt(struct cpsw_pla
 				 PHY_ID_FMT, mdio->name, phyid);
 			put_device(&mdio->dev);
 		} else {
-			dev_err(&pdev->dev, "No slave[%d] phy_id or fixed-link property\n", i);
+			dev_err(&pdev->dev,
+				"No slave[%d] phy_id, phy-handle, or fixed-link property\n",
+				i);
 			goto no_phy_slave;
 		}
 		slave_data->phy_if = of_get_phy_mode(slave_node);
@@ -2526,12 +2532,14 @@ static int cpsw_probe(struct platform_de
 		ret = cpsw_probe_dual_emac(pdev, priv);
 		if (ret) {
 			cpsw_err(priv, probe, "error probe slave 2 emac interface\n");
-			goto clean_ale_ret;
+			goto clean_unregister_netdev_ret;
 		}
 	}
 
 	return 0;
 
+clean_unregister_netdev_ret:
+	unregister_netdev(ndev);
 clean_ale_ret:
 	cpsw_ale_destroy(priv->ale);
 clean_dma_ret:
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/ti/cpsw-phy-sel.c linux-libre-4.4.223-gnu/drivers/net/ethernet/ti/cpsw-phy-sel.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/ti/cpsw-phy-sel.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/ti/cpsw-phy-sel.c	2020-05-10 04:26:37.000000000 -0400
@@ -154,9 +154,12 @@ void cpsw_phy_sel(struct device *dev, ph
 	}
 
 	dev = bus_find_device(&platform_bus_type, NULL, node, match);
+	of_node_put(node);
 	priv = dev_get_drvdata(dev);
 
 	priv->cpsw_phy_sel(priv, phy_mode, slave);
+
+	put_device(dev);
 }
 EXPORT_SYMBOL_GPL(cpsw_phy_sel);
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/ti/davinci_emac.c linux-libre-4.4.223-gnu/drivers/net/ethernet/ti/davinci_emac.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/ti/davinci_emac.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/ti/davinci_emac.c	2020-05-10 04:26:37.000000000 -0400
@@ -1512,7 +1512,10 @@ static int emac_devioctl(struct net_devi
 
 	/* TODO: Add phy read and write and private statistics get feature */
 
-	return phy_mii_ioctl(priv->phydev, ifrq, cmd);
+	if (priv->phydev)
+		return phy_mii_ioctl(priv->phydev, ifrq, cmd);
+	else
+		return -EOPNOTSUPP;
 }
 
 static int match_first_device(struct device *dev, void *data)
@@ -1885,8 +1888,6 @@ davinci_emac_of_get_pdata(struct platfor
 		pdata->hw_ram_addr = auxdata->hw_ram_addr;
 	}
 
-	pdev->dev.platform_data = pdata;
-
 	return  pdata;
 }
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/ethernet/xilinx/xilinx_axienet_main.c linux-libre-4.4.223-gnu/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
--- linux-libre-4.4.222-gnu/drivers/net/ethernet/xilinx/xilinx_axienet_main.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/ethernet/xilinx/xilinx_axienet_main.c	2020-05-10 04:26:37.000000000 -0400
@@ -1602,9 +1602,9 @@ static int axienet_probe(struct platform
 
 	/* Find the DMA node, map the DMA registers, and decode the DMA IRQs */
 	np = of_parse_phandle(pdev->dev.of_node, "axistream-connected", 0);
-	if (IS_ERR(np)) {
+	if (!np) {
 		dev_err(&pdev->dev, "could not find DMA node\n");
-		ret = PTR_ERR(np);
+		ret = -ENODEV;
 		goto free_netdev;
 	}
 	ret = of_address_to_resource(np, 0, &dmares);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/geneve.c linux-libre-4.4.223-gnu/drivers/net/geneve.c
--- linux-libre-4.4.222-gnu/drivers/net/geneve.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/geneve.c	2020-05-10 04:26:37.000000000 -0400
@@ -1340,6 +1340,7 @@ struct net_device *geneve_dev_create_fb(
 {
 	struct nlattr *tb[IFLA_MAX + 1];
 	struct net_device *dev;
+	LIST_HEAD(list_kill);
 	int err;
 
 	memset(tb, 0, sizeof(tb));
@@ -1350,8 +1351,10 @@ struct net_device *geneve_dev_create_fb(
 
 	err = geneve_configure(net, dev, &geneve_remote_unspec,
 			       0, 0, 0, htons(dst_port), true);
-	if (err)
-		goto err;
+	if (err) {
+		free_netdev(dev);
+		return ERR_PTR(err);
+	}
 
 	/* openvswitch users expect packet sizes to be unrestricted,
 	 * so set the largest MTU we can.
@@ -1360,10 +1363,15 @@ struct net_device *geneve_dev_create_fb(
 	if (err)
 		goto err;
 
+	err = rtnl_configure_link(dev, NULL);
+	if (err < 0)
+		goto err;
+
 	return dev;
 
  err:
-	free_netdev(dev);
+	geneve_dellink(dev, &list_kill);
+	unregister_netdevice_many(&list_kill);
 	return ERR_PTR(err);
 }
 EXPORT_SYMBOL_GPL(geneve_dev_create_fb);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/macvlan.c linux-libre-4.4.223-gnu/drivers/net/macvlan.c
--- linux-libre-4.4.222-gnu/drivers/net/macvlan.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/macvlan.c	2020-05-10 04:26:37.000000000 -0400
@@ -305,6 +305,8 @@ static void macvlan_process_broadcast(st
 
 		rcu_read_unlock();
 
+		if (src)
+			dev_put(src->dev);
 		kfree_skb(skb);
 
 		cond_resched();
@@ -312,6 +314,7 @@ static void macvlan_process_broadcast(st
 }
 
 static void macvlan_broadcast_enqueue(struct macvlan_port *port,
+				      const struct macvlan_dev *src,
 				      struct sk_buff *skb)
 {
 	struct sk_buff *nskb;
@@ -321,8 +324,12 @@ static void macvlan_broadcast_enqueue(st
 	if (!nskb)
 		goto err;
 
+	MACVLAN_SKB_CB(nskb)->src = src;
+
 	spin_lock(&port->bc_queue.lock);
 	if (skb_queue_len(&port->bc_queue) < MACVLAN_BC_QUEUE_LEN) {
+		if (src)
+			dev_hold(src->dev);
 		__skb_queue_tail(&port->bc_queue, nskb);
 		err = 0;
 	}
@@ -432,8 +439,7 @@ static rx_handler_result_t macvlan_handl
 			goto out;
 		}
 
-		MACVLAN_SKB_CB(skb)->src = src;
-		macvlan_broadcast_enqueue(port, skb);
+		macvlan_broadcast_enqueue(port, src, skb);
 
 		return RX_HANDLER_PASS;
 	}
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/macvtap.c linux-libre-4.4.223-gnu/drivers/net/macvtap.c
--- linux-libre-4.4.222-gnu/drivers/net/macvtap.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/macvtap.c	2020-05-10 04:26:37.000000000 -0400
@@ -373,7 +373,7 @@ static rx_handler_result_t macvtap_handl
 			goto wake_up;
 		}
 
-		kfree_skb(skb);
+		consume_skb(skb);
 		while (segs) {
 			struct sk_buff *nskb = segs->next;
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/phy/at803x.c linux-libre-4.4.223-gnu/drivers/net/phy/at803x.c
--- linux-libre-4.4.222-gnu/drivers/net/phy/at803x.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/phy/at803x.c	2020-05-10 04:26:37.000000000 -0400
@@ -198,7 +198,7 @@ static int at803x_probe(struct phy_devic
 	if (!priv)
 		return -ENOMEM;
 
-	gpiod_reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
+	gpiod_reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
 	if (IS_ERR(gpiod_reset))
 		return PTR_ERR(gpiod_reset);
 
@@ -274,10 +274,10 @@ static void at803x_link_change_notify(st
 
 				at803x_context_save(phydev, &context);
 
-				gpiod_set_value(priv->gpiod_reset, 0);
-				msleep(1);
 				gpiod_set_value(priv->gpiod_reset, 1);
 				msleep(1);
+				gpiod_set_value(priv->gpiod_reset, 0);
+				msleep(1);
 
 				at803x_context_restore(phydev, &context);
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/phy/bcm7xxx.c linux-libre-4.4.223-gnu/drivers/net/phy/bcm7xxx.c
--- linux-libre-4.4.222-gnu/drivers/net/phy/bcm7xxx.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/phy/bcm7xxx.c	2020-05-10 04:26:37.000000000 -0400
@@ -270,7 +270,7 @@ static int bcm7xxx_config_init(struct ph
 	phy_write(phydev, MII_BCM7XXX_100TX_FALSE_CAR, 0x7555);
 
 	/* reset shadow mode 2 */
-	ret = phy_set_clr_bits(phydev, MII_BCM7XXX_TEST, MII_BCM7XXX_SHD_MODE_2, 0);
+	ret = phy_set_clr_bits(phydev, MII_BCM7XXX_TEST, 0, MII_BCM7XXX_SHD_MODE_2);
 	if (ret < 0)
 		return ret;
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/phy/mdio-sun4i.c linux-libre-4.4.223-gnu/drivers/net/phy/mdio-sun4i.c
--- linux-libre-4.4.222-gnu/drivers/net/phy/mdio-sun4i.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/phy/mdio-sun4i.c	2020-05-10 04:26:37.000000000 -0400
@@ -134,6 +134,7 @@ static int sun4i_mdio_probe(struct platf
 		}
 
 		dev_info(&pdev->dev, "no regulator found\n");
+		data->regulator = NULL;
 	} else {
 		ret = regulator_enable(data->regulator);
 		if (ret)
@@ -149,7 +150,8 @@ static int sun4i_mdio_probe(struct platf
 	return 0;
 
 err_out_disable_regulator:
-	regulator_disable(data->regulator);
+	if (data->regulator)
+		regulator_disable(data->regulator);
 err_out_free_mdiobus:
 	mdiobus_free(bus);
 	return ret;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/phy/micrel.c linux-libre-4.4.223-gnu/drivers/net/phy/micrel.c
--- linux-libre-4.4.222-gnu/drivers/net/phy/micrel.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/phy/micrel.c	2020-05-10 04:26:37.000000000 -0400
@@ -482,9 +482,17 @@ static int ksz9031_config_init(struct ph
 		"txd2-skew-ps", "txd3-skew-ps"
 	};
 	static const char *control_skews[2] = {"txen-skew-ps", "rxdv-skew-ps"};
+	const struct device *dev_walker;
 
-	if (!of_node && dev->parent->of_node)
-		of_node = dev->parent->of_node;
+	/* The Micrel driver has a deprecated option to place phy OF
+	 * properties in the MAC node. Walk up the tree of devices to
+	 * find a device with an OF node.
+	 */
+	dev_walker = &phydev->dev;
+	do {
+		of_node = dev_walker->of_node;
+		dev_walker = dev_walker->parent;
+	} while (!of_node && dev_walker);
 
 	if (of_node) {
 		ksz9031_of_load_skew_values(phydev, of_node,
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/phy/phy.c linux-libre-4.4.223-gnu/drivers/net/phy/phy.c
--- linux-libre-4.4.222-gnu/drivers/net/phy/phy.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/phy/phy.c	2020-05-10 04:26:37.000000000 -0400
@@ -699,25 +699,29 @@ void phy_change(struct work_struct *work
 	struct phy_device *phydev =
 		container_of(work, struct phy_device, phy_queue);
 
-	if (phydev->drv->did_interrupt &&
-	    !phydev->drv->did_interrupt(phydev))
-		goto ignore;
+	if (phy_interrupt_is_valid(phydev)) {
+		if (phydev->drv->did_interrupt &&
+		    !phydev->drv->did_interrupt(phydev))
+			goto ignore;
 
-	if (phy_disable_interrupts(phydev))
-		goto phy_err;
+		if (phy_disable_interrupts(phydev))
+			goto phy_err;
+	}
 
 	mutex_lock(&phydev->lock);
 	if ((PHY_RUNNING == phydev->state) || (PHY_NOLINK == phydev->state))
 		phydev->state = PHY_CHANGELINK;
 	mutex_unlock(&phydev->lock);
 
-	atomic_dec(&phydev->irq_disable);
-	enable_irq(phydev->irq);
+	if (phy_interrupt_is_valid(phydev)) {
+		atomic_dec(&phydev->irq_disable);
+		enable_irq(phydev->irq);
 
-	/* Reenable interrupts */
-	if (PHY_HALTED != phydev->state &&
-	    phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED))
-		goto irq_enable_err;
+		/* Reenable interrupts */
+		if (PHY_HALTED != phydev->state &&
+		    phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED))
+			goto irq_enable_err;
+	}
 
 	/* reschedule state queue work to run as soon as possible */
 	cancel_delayed_work_sync(&phydev->state_queue);
@@ -912,10 +916,10 @@ void phy_state_machine(struct work_struc
 		phydev->adjust_link(phydev->attached_dev);
 		break;
 	case PHY_RUNNING:
-		/* Only register a CHANGE if we are polling or ignoring
-		 * interrupts and link changed since latest checking.
+		/* Only register a CHANGE if we are polling and link changed
+		 * since latest checking.
 		 */
-		if (!phy_interrupt_is_valid(phydev)) {
+		if (phydev->irq == PHY_POLL) {
 			old_link = phydev->link;
 			err = phy_read_status(phydev);
 			if (err)
@@ -1015,15 +1019,21 @@ void phy_state_machine(struct work_struc
 	dev_dbg(&phydev->dev, "PHY state change %s -> %s\n",
 		phy_state_to_str(old_state), phy_state_to_str(phydev->state));
 
-	queue_delayed_work(system_power_efficient_wq, &phydev->state_queue,
-			   PHY_STATE_TIME * HZ);
+	/* Only re-schedule a PHY state machine change if we are polling the
+	 * PHY, if PHY_IGNORE_INTERRUPT is set, then we will be moving
+	 * between states from phy_mac_interrupt()
+	 */
+	if (phydev->irq == PHY_POLL)
+		queue_delayed_work(system_power_efficient_wq, &phydev->state_queue,
+				   PHY_STATE_TIME * HZ);
 }
 
 void phy_mac_interrupt(struct phy_device *phydev, int new_link)
 {
-	cancel_work_sync(&phydev->phy_queue);
 	phydev->link = new_link;
-	schedule_work(&phydev->phy_queue);
+
+	/* Trigger a state machine change */
+	queue_work(system_power_efficient_wq, &phydev->phy_queue);
 }
 EXPORT_SYMBOL(phy_mac_interrupt);
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/phy/phy_device.c linux-libre-4.4.223-gnu/drivers/net/phy/phy_device.c
--- linux-libre-4.4.222-gnu/drivers/net/phy/phy_device.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/phy/phy_device.c	2020-05-10 04:26:37.000000000 -0400
@@ -522,6 +522,7 @@ struct phy_device *phy_connect(struct ne
 	phydev = to_phy_device(d);
 
 	rc = phy_connect_direct(dev, phydev, handler, interface);
+	put_device(d);
 	if (rc)
 		return ERR_PTR(rc);
 
@@ -721,6 +722,7 @@ struct phy_device *phy_attach(struct net
 	phydev = to_phy_device(d);
 
 	rc = phy_attach_direct(dev, phydev, phydev->dev_flags, interface);
+	put_device(d);
 	if (rc)
 		return ERR_PTR(rc);
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/vrf.c linux-libre-4.4.223-gnu/drivers/net/vrf.c
--- linux-libre-4.4.222-gnu/drivers/net/vrf.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/vrf.c	2020-05-10 04:26:37.000000000 -0400
@@ -71,41 +71,6 @@ struct pcpu_dstats {
 	struct u64_stats_sync	syncp;
 };
 
-static struct dst_entry *vrf_ip_check(struct dst_entry *dst, u32 cookie)
-{
-	return dst;
-}
-
-static int vrf_ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb)
-{
-	return ip_local_out(net, sk, skb);
-}
-
-static unsigned int vrf_v4_mtu(const struct dst_entry *dst)
-{
-	/* TO-DO: return max ethernet size? */
-	return dst->dev->mtu;
-}
-
-static void vrf_dst_destroy(struct dst_entry *dst)
-{
-	/* our dst lives forever - or until the device is closed */
-}
-
-static unsigned int vrf_default_advmss(const struct dst_entry *dst)
-{
-	return 65535 - 40;
-}
-
-static struct dst_ops vrf_dst_ops = {
-	.family		= AF_INET,
-	.local_out	= vrf_ip_local_out,
-	.check		= vrf_ip_check,
-	.mtu		= vrf_v4_mtu,
-	.destroy	= vrf_dst_destroy,
-	.default_advmss	= vrf_default_advmss,
-};
-
 /* neighbor handling is done with actual device; do not want
  * to flip skb->dev for those ndisc packets. This really fails
  * for multiple next protocols (e.g., NEXTHDR_HOP). But it is
@@ -363,46 +328,6 @@ static netdev_tx_t vrf_xmit(struct sk_bu
 }
 
 #if IS_ENABLED(CONFIG_IPV6)
-static struct dst_entry *vrf_ip6_check(struct dst_entry *dst, u32 cookie)
-{
-	return dst;
-}
-
-static struct dst_ops vrf_dst_ops6 = {
-	.family		= AF_INET6,
-	.local_out	= ip6_local_out,
-	.check		= vrf_ip6_check,
-	.mtu		= vrf_v4_mtu,
-	.destroy	= vrf_dst_destroy,
-	.default_advmss	= vrf_default_advmss,
-};
-
-static int init_dst_ops6_kmem_cachep(void)
-{
-	vrf_dst_ops6.kmem_cachep = kmem_cache_create("vrf_ip6_dst_cache",
-						     sizeof(struct rt6_info),
-						     0,
-						     SLAB_HWCACHE_ALIGN,
-						     NULL);
-
-	if (!vrf_dst_ops6.kmem_cachep)
-		return -ENOMEM;
-
-	return 0;
-}
-
-static void free_dst_ops6_kmem_cachep(void)
-{
-	kmem_cache_destroy(vrf_dst_ops6.kmem_cachep);
-}
-
-static int vrf_input6(struct sk_buff *skb)
-{
-	skb->dev->stats.rx_errors++;
-	kfree_skb(skb);
-	return 0;
-}
-
 /* modelled after ip6_finish_output2 */
 static int vrf_finish_output6(struct net *net, struct sock *sk,
 			      struct sk_buff *skb)
@@ -445,67 +370,34 @@ static int vrf_output6(struct net *net,
 			    !(IP6CB(skb)->flags & IP6SKB_REROUTED));
 }
 
-static void vrf_rt6_destroy(struct net_vrf *vrf)
+static void vrf_rt6_release(struct net_vrf *vrf)
 {
-	dst_destroy(&vrf->rt6->dst);
-	free_percpu(vrf->rt6->rt6i_pcpu);
+	dst_release(&vrf->rt6->dst);
 	vrf->rt6 = NULL;
 }
 
 static int vrf_rt6_create(struct net_device *dev)
 {
 	struct net_vrf *vrf = netdev_priv(dev);
-	struct dst_entry *dst;
+	struct net *net = dev_net(dev);
 	struct rt6_info *rt6;
-	int cpu;
 	int rc = -ENOMEM;
 
-	rt6 = dst_alloc(&vrf_dst_ops6, dev, 0,
-			DST_OBSOLETE_NONE,
-			(DST_HOST | DST_NOPOLICY | DST_NOXFRM));
+	rt6 = ip6_dst_alloc(net, dev,
+			    DST_HOST | DST_NOPOLICY | DST_NOXFRM | DST_NOCACHE);
 	if (!rt6)
 		goto out;
 
-	dst = &rt6->dst;
-
-	rt6->rt6i_pcpu = alloc_percpu_gfp(struct rt6_info *, GFP_KERNEL);
-	if (!rt6->rt6i_pcpu) {
-		dst_destroy(dst);
-		goto out;
-	}
-	for_each_possible_cpu(cpu) {
-		struct rt6_info **p = per_cpu_ptr(rt6->rt6i_pcpu, cpu);
-		*p =  NULL;
-	}
-
-	memset(dst + 1, 0, sizeof(*rt6) - sizeof(*dst));
-
-	INIT_LIST_HEAD(&rt6->rt6i_siblings);
-	INIT_LIST_HEAD(&rt6->rt6i_uncached);
-
-	rt6->dst.input	= vrf_input6;
 	rt6->dst.output	= vrf_output6;
-
-	rt6->rt6i_table = fib6_get_table(dev_net(dev), vrf->tb_id);
-
-	atomic_set(&rt6->dst.__refcnt, 2);
-
+	rt6->rt6i_table = fib6_get_table(net, vrf->tb_id);
+	dst_hold(&rt6->dst);
 	vrf->rt6 = rt6;
 	rc = 0;
 out:
 	return rc;
 }
 #else
-static int init_dst_ops6_kmem_cachep(void)
-{
-	return 0;
-}
-
-static void free_dst_ops6_kmem_cachep(void)
-{
-}
-
-static void vrf_rt6_destroy(struct net_vrf *vrf)
+static void vrf_rt6_release(struct net_vrf *vrf)
 {
 }
 
@@ -577,11 +469,11 @@ static int vrf_output(struct net *net, s
 			    !(IPCB(skb)->flags & IPSKB_REROUTED));
 }
 
-static void vrf_rtable_destroy(struct net_vrf *vrf)
+static void vrf_rtable_release(struct net_vrf *vrf)
 {
 	struct dst_entry *dst = (struct dst_entry *)vrf->rth;
 
-	dst_destroy(dst);
+	dst_release(dst);
 	vrf->rth = NULL;
 }
 
@@ -590,22 +482,10 @@ static struct rtable *vrf_rtable_create(
 	struct net_vrf *vrf = netdev_priv(dev);
 	struct rtable *rth;
 
-	rth = dst_alloc(&vrf_dst_ops, dev, 2,
-			DST_OBSOLETE_NONE,
-			(DST_HOST | DST_NOPOLICY | DST_NOXFRM));
+	rth = rt_dst_alloc(dev, 0, RTN_UNICAST, 1, 1, 0);
 	if (rth) {
 		rth->dst.output	= vrf_output;
-		rth->rt_genid	= rt_genid_ipv4(dev_net(dev));
-		rth->rt_flags	= 0;
-		rth->rt_type	= RTN_UNICAST;
-		rth->rt_is_input = 0;
-		rth->rt_iif	= 0;
-		rth->rt_pmtu	= 0;
-		rth->rt_gateway	= 0;
-		rth->rt_uses_gateway = 0;
 		rth->rt_table_id = vrf->tb_id;
-		INIT_LIST_HEAD(&rth->rt_uncached);
-		rth->rt_uncached_list = NULL;
 	}
 
 	return rth;
@@ -739,8 +619,8 @@ static void vrf_dev_uninit(struct net_de
 //	struct list_head *head = &queue->all_slaves;
 //	struct slave *slave, *next;
 
-	vrf_rtable_destroy(vrf);
-	vrf_rt6_destroy(vrf);
+	vrf_rtable_release(vrf);
+	vrf_rt6_release(vrf);
 
 //	list_for_each_entry_safe(slave, next, head, list)
 //		vrf_del_slave(dev, slave->dev);
@@ -772,7 +652,7 @@ static int vrf_dev_init(struct net_devic
 	return 0;
 
 out_rth:
-	vrf_rtable_destroy(vrf);
+	vrf_rtable_release(vrf);
 out_stats:
 	free_percpu(dev->dstats);
 	dev->dstats = NULL;
@@ -805,7 +685,7 @@ static struct rtable *vrf_get_rtable(con
 		struct net_vrf *vrf = netdev_priv(dev);
 
 		rth = vrf->rth;
-		atomic_inc(&rth->dst.__refcnt);
+		dst_hold(&rth->dst);
 	}
 
 	return rth;
@@ -856,7 +736,7 @@ static struct dst_entry *vrf_get_rt6_dst
 		struct net_vrf *vrf = netdev_priv(dev);
 
 		rt = vrf->rt6;
-		atomic_inc(&rt->dst.__refcnt);
+		dst_hold(&rt->dst);
 	}
 
 	return (struct dst_entry *)rt;
@@ -1003,19 +883,6 @@ static int __init vrf_init_module(void)
 {
 	int rc;
 
-	vrf_dst_ops.kmem_cachep =
-		kmem_cache_create("vrf_ip_dst_cache",
-				  sizeof(struct rtable), 0,
-				  SLAB_HWCACHE_ALIGN,
-				  NULL);
-
-	if (!vrf_dst_ops.kmem_cachep)
-		return -ENOMEM;
-
-	rc = init_dst_ops6_kmem_cachep();
-	if (rc != 0)
-		goto error2;
-
 	register_netdevice_notifier(&vrf_notifier_block);
 
 	rc = rtnl_link_register(&vrf_link_ops);
@@ -1026,22 +893,10 @@ static int __init vrf_init_module(void)
 
 error:
 	unregister_netdevice_notifier(&vrf_notifier_block);
-	free_dst_ops6_kmem_cachep();
-error2:
-	kmem_cache_destroy(vrf_dst_ops.kmem_cachep);
 	return rc;
 }
 
-static void __exit vrf_cleanup_module(void)
-{
-	rtnl_link_unregister(&vrf_link_ops);
-	unregister_netdevice_notifier(&vrf_notifier_block);
-	kmem_cache_destroy(vrf_dst_ops.kmem_cachep);
-	free_dst_ops6_kmem_cachep();
-}
-
 module_init(vrf_init_module);
-module_exit(vrf_cleanup_module);
 MODULE_AUTHOR("Shrijeet Mukherjee, David Ahern");
 MODULE_DESCRIPTION("Device driver to instantiate VRF domains");
 MODULE_LICENSE("GPL");
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/vxlan.c linux-libre-4.4.223-gnu/drivers/net/vxlan.c
--- linux-libre-4.4.222-gnu/drivers/net/vxlan.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/vxlan.c	2020-05-10 04:26:37.000000000 -0400
@@ -2054,7 +2054,7 @@ static void vxlan_xmit_one(struct sk_buf
 		}
 
 		/* Bypass encapsulation if the destination is local */
-		if (rt->rt_flags & RTCF_LOCAL &&
+		if (!info && rt->rt_flags & RTCF_LOCAL &&
 		    !(rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))) {
 			struct vxlan_dev *dst_vxlan;
 
@@ -2112,7 +2112,7 @@ static void vxlan_xmit_one(struct sk_buf
 
 		/* Bypass encapsulation if the destination is local */
 		rt6i_flags = ((struct rt6_info *)ndst)->rt6i_flags;
-		if (rt6i_flags & RTF_LOCAL &&
+		if (!info && rt6i_flags & RTF_LOCAL &&
 		    !(rt6i_flags & (RTCF_BROADCAST | RTCF_MULTICAST))) {
 			struct vxlan_dev *dst_vxlan;
 
@@ -2927,30 +2927,6 @@ static int vxlan_dev_configure(struct ne
 	return 0;
 }
 
-struct net_device *vxlan_dev_create(struct net *net, const char *name,
-				    u8 name_assign_type, struct vxlan_config *conf)
-{
-	struct nlattr *tb[IFLA_MAX+1];
-	struct net_device *dev;
-	int err;
-
-	memset(&tb, 0, sizeof(tb));
-
-	dev = rtnl_create_link(net, name, name_assign_type,
-			       &vxlan_link_ops, tb);
-	if (IS_ERR(dev))
-		return dev;
-
-	err = vxlan_dev_configure(net, dev, conf);
-	if (err < 0) {
-		free_netdev(dev);
-		return ERR_PTR(err);
-	}
-
-	return dev;
-}
-EXPORT_SYMBOL_GPL(vxlan_dev_create);
-
 static int vxlan_newlink(struct net *src_net, struct net_device *dev,
 			 struct nlattr *tb[], struct nlattr *data[])
 {
@@ -3218,6 +3194,40 @@ static struct rtnl_link_ops vxlan_link_o
 	.get_link_net	= vxlan_get_link_net,
 };
 
+struct net_device *vxlan_dev_create(struct net *net, const char *name,
+				    u8 name_assign_type,
+				    struct vxlan_config *conf)
+{
+	struct nlattr *tb[IFLA_MAX + 1];
+	struct net_device *dev;
+	int err;
+
+	memset(&tb, 0, sizeof(tb));
+
+	dev = rtnl_create_link(net, name, name_assign_type,
+			       &vxlan_link_ops, tb);
+	if (IS_ERR(dev))
+		return dev;
+
+	err = vxlan_dev_configure(net, dev, conf);
+	if (err < 0) {
+		free_netdev(dev);
+		return ERR_PTR(err);
+	}
+
+	err = rtnl_configure_link(dev, NULL);
+	if (err < 0) {
+		LIST_HEAD(list_kill);
+
+		vxlan_dellink(dev, &list_kill);
+		unregister_netdevice_many(&list_kill);
+		return ERR_PTR(err);
+	}
+
+	return dev;
+}
+EXPORT_SYMBOL_GPL(vxlan_dev_create);
+
 static void vxlan_handle_lowerdev_unregister(struct vxlan_net *vn,
 					     struct net_device *dev)
 {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/wimax/i2400m/usb-fw.c linux-libre-4.4.223-gnu/drivers/net/wimax/i2400m/usb-fw.c
--- linux-libre-4.4.222-gnu/drivers/net/wimax/i2400m/usb-fw.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/wimax/i2400m/usb-fw.c	2020-05-10 04:26:37.000000000 -0400
@@ -354,6 +354,7 @@ out:
 		usb_autopm_put_interface(i2400mu->usb_iface);
 	d_fnend(8, dev, "(i2400m %p ack %p size %zu) = %ld\n",
 		i2400m, ack, ack_size, (long) result);
+	usb_put_urb(&notif_urb);
 	return result;
 
 error_exceeded:
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/wireless/ath/ath10k/core.c linux-libre-4.4.223-gnu/drivers/net/wireless/ath/ath10k/core.c
--- linux-libre-4.4.222-gnu/drivers/net/wireless/ath/ath10k/core.c	2020-05-05 15:36:53.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/wireless/ath/ath10k/core.c	2020-05-10 19:02:19.000000000 -0400
@@ -1805,7 +1805,7 @@ static int ath10k_core_probe_fw(struct a
 	if (ret && ret != -EOPNOTSUPP) {
 		ath10k_err(ar, "failed to get board id from otp for qca99x0: %d\n",
 			   ret);
-		return ret;
+		goto err_free_firmware_files;
 	}
 
 	ret = ath10k_core_fetch_board_file(ar);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/wireless/ath/ath9k/htc_hst.c linux-libre-4.4.223-gnu/drivers/net/wireless/ath/ath9k/htc_hst.c
--- linux-libre-4.4.222-gnu/drivers/net/wireless/ath/ath9k/htc_hst.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/wireless/ath/ath9k/htc_hst.c	2020-05-10 04:26:37.000000000 -0400
@@ -414,7 +414,7 @@ void ath9k_htc_rx_msg(struct htc_target
 		return;
 	}
 
-	if (epid >= ENDPOINT_MAX) {
+	if (epid < 0 || epid >= ENDPOINT_MAX) {
 		if (pipe_id != USB_REG_IN_PIPE)
 			dev_kfree_skb_any(skb);
 		else
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c linux-libre-4.4.223-gnu/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
--- linux-libre-4.4.222-gnu/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c	2020-05-10 04:26:37.000000000 -0400
@@ -2419,12 +2419,14 @@ brcmf_cfg80211_get_station(struct wiphy
 			   const u8 *mac, struct station_info *sinfo)
 {
 	struct brcmf_if *ifp = netdev_priv(ndev);
+	struct brcmf_scb_val_le scb_val;
 	s32 err = 0;
 	struct brcmf_sta_info_le sta_info_le;
 	u32 sta_flags;
 	u32 is_tdls_peer;
 	s32 total_rssi;
 	s32 count_rssi;
+	int rssi;
 	u32 i;
 
 	brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
@@ -2505,6 +2507,20 @@ brcmf_cfg80211_get_station(struct wiphy
 			sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
 			total_rssi /= count_rssi;
 			sinfo->signal = total_rssi;
+		} else if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
+			&ifp->vif->sme_state)) {
+			memset(&scb_val, 0, sizeof(scb_val));
+			err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
+						     &scb_val, sizeof(scb_val));
+			if (err) {
+				brcmf_err("Could not get rssi (%d)\n", err);
+				goto done;
+			} else {
+				rssi = le32_to_cpu(scb_val.val);
+				sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
+				sinfo->signal = rssi;
+				brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
+			}
 		}
 	}
 done:
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c linux-libre-4.4.223-gnu/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
--- linux-libre-4.4.222-gnu/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c	2020-05-10 04:26:37.000000000 -0400
@@ -2262,10 +2262,22 @@ void brcmf_fws_bustxfail(struct brcmf_fw
 void brcmf_fws_bus_blocked(struct brcmf_pub *drvr, bool flow_blocked)
 {
 	struct brcmf_fws_info *fws = drvr->fws;
+	struct brcmf_if *ifp;
+	int i;
 
-	fws->bus_flow_blocked = flow_blocked;
-	if (!flow_blocked)
-		brcmf_fws_schedule_deq(fws);
-	else
-		fws->stats.bus_flow_block++;
+	if (fws->avoid_queueing) {
+		for (i = 0; i < BRCMF_MAX_IFS; i++) {
+			ifp = drvr->iflist[i];
+			if (!ifp || !ifp->ndev)
+				continue;
+			brcmf_txflowblock_if(ifp, BRCMF_NETIF_STOP_REASON_FLOW,
+					     flow_blocked);
+		}
+	} else {
+		fws->bus_flow_blocked = flow_blocked;
+		if (!flow_blocked)
+			brcmf_fws_schedule_deq(fws);
+		else
+			fws->stats.bus_flow_block++;
+	}
 }
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c linux-libre-4.4.223-gnu/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
--- linux-libre-4.4.222-gnu/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c	2020-05-10 04:26:37.000000000 -0400
@@ -1155,6 +1155,8 @@ brcmf_msgbuf_process_rx_complete(struct
 		brcmu_pkt_buf_free_skb(skb);
 		return;
 	}
+
+	skb->protocol = eth_type_trans(skb, ifp->ndev);
 	brcmf_netif_rx(ifp, skb);
 }
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/wireless/iwlwifi/iwl-7000.c linux-libre-4.4.223-gnu/drivers/net/wireless/iwlwifi/iwl-7000.c
--- linux-libre-4.4.222-gnu/drivers/net/wireless/iwlwifi/iwl-7000.c	2020-05-05 15:34:03.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/wireless/iwlwifi/iwl-7000.c	2020-05-10 19:01:05.000000000 -0400
@@ -70,7 +70,7 @@
 
 /* Highest firmware API version supported */
 #define IWL7260_UCODE_API_MAX	17
-#define IWL7265_UCODE_API_MAX	19
+#define IWL7265_UCODE_API_MAX	17
 #define IWL7265D_UCODE_API_MAX	19
 
 /* Oldest version we won't warn about */
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/wireless/mwifiex/pcie.h linux-libre-4.4.223-gnu/drivers/net/wireless/mwifiex/pcie.h
--- linux-libre-4.4.222-gnu/drivers/net/wireless/mwifiex/pcie.h	2020-05-05 15:36:10.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/wireless/mwifiex/pcie.h	2020-05-10 19:01:40.000000000 -0400
@@ -210,17 +210,17 @@ static const struct mwifiex_pcie_card_re
 	.cmdrsp_addr_lo = PCIE_SCRATCH_4_REG,
 	.cmdrsp_addr_hi = PCIE_SCRATCH_5_REG,
 	.tx_rdptr = 0xC1A4,
-	.tx_wrptr = 0xC1A8,
-	.rx_rdptr = 0xC1A8,
+	.tx_wrptr = 0xC174,
+	.rx_rdptr = 0xC174,
 	.rx_wrptr = 0xC1A4,
 	.evt_rdptr = PCIE_SCRATCH_10_REG,
 	.evt_wrptr = PCIE_SCRATCH_11_REG,
 	.drv_rdy = PCIE_SCRATCH_12_REG,
 	.tx_start_ptr = 16,
 	.tx_mask = 0x0FFF0000,
-	.tx_wrap_mask = 0x01FF0000,
+	.tx_wrap_mask = 0x1FFF0000,
 	.rx_mask = 0x00000FFF,
-	.rx_wrap_mask = 0x000001FF,
+	.rx_wrap_mask = 0x00001FFF,
 	.tx_rollover_ind = BIT(28),
 	.rx_rollover_ind = BIT(12),
 	.evt_rollover_ind = MWIFIEX_BD_FLAG_EVT_ROLLOVER_IND,
@@ -342,6 +342,7 @@ mwifiex_pcie_txbd_empty(struct pcie_serv
 			return 1;
 		break;
 	case PCIE_DEVICE_ID_MARVELL_88W8897:
+	case PCIE_DEVICE_ID_MARVELL_88W8997:
 		if (((card->txbd_wrptr & reg->tx_mask) ==
 		     (rdptr & reg->tx_mask)) &&
 		    ((card->txbd_wrptr & reg->tx_rollover_ind) ==
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/wireless/mwifiex/sta_event.c linux-libre-4.4.223-gnu/drivers/net/wireless/mwifiex/sta_event.c
--- linux-libre-4.4.222-gnu/drivers/net/wireless/mwifiex/sta_event.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/wireless/mwifiex/sta_event.c	2020-05-10 04:26:37.000000000 -0400
@@ -607,11 +607,13 @@ int mwifiex_process_sta_event(struct mwi
 
 	case EVENT_PS_AWAKE:
 		mwifiex_dbg(adapter, EVENT, "info: EVENT: AWAKE\n");
-		if (!adapter->pps_uapsd_mode && priv->port_open &&
+		if (!adapter->pps_uapsd_mode &&
+		    (priv->port_open ||
+		     (priv->bss_mode == NL80211_IFTYPE_ADHOC)) &&
 		    priv->media_connected && adapter->sleep_period.period) {
-				adapter->pps_uapsd_mode = true;
-				mwifiex_dbg(adapter, EVENT,
-					    "event: PPS/UAPSD mode activated\n");
+			adapter->pps_uapsd_mode = true;
+			mwifiex_dbg(adapter, EVENT,
+				    "event: PPS/UAPSD mode activated\n");
 		}
 		adapter->tx_lock_flag = false;
 		if (adapter->pps_uapsd_mode && adapter->gen_null_pkt) {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/net/wireless/mwifiex/wmm.c linux-libre-4.4.223-gnu/drivers/net/wireless/mwifiex/wmm.c
--- linux-libre-4.4.222-gnu/drivers/net/wireless/mwifiex/wmm.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/net/wireless/mwifiex/wmm.c	2020-05-10 04:26:37.000000000 -0400
@@ -475,7 +475,8 @@ mwifiex_wmm_lists_empty(struct mwifiex_a
 		priv = adapter->priv[i];
 		if (!priv)
 			continue;
-		if (!priv->port_open)
+		if (!priv->port_open &&
+		    (priv->bss_mode != NL80211_IFTYPE_ADHOC))
 			continue;
 		if (adapter->if_ops.is_port_ready &&
 		    !adapter->if_ops.is_port_ready(priv))
@@ -1109,7 +1110,8 @@ mwifiex_wmm_get_highest_priolist_ptr(str
 
 			priv_tmp = adapter->bss_prio_tbl[j].bss_prio_cur->priv;
 
-			if (!priv_tmp->port_open ||
+			if (((priv_tmp->bss_mode != NL80211_IFTYPE_ADHOC) &&
+			     !priv_tmp->port_open) ||
 			    (atomic_read(&priv_tmp->wmm.tx_pkts_queued) == 0))
 				continue;
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/of/of_mdio.c linux-libre-4.4.223-gnu/drivers/of/of_mdio.c
--- linux-libre-4.4.222-gnu/drivers/of/of_mdio.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/of/of_mdio.c	2020-05-10 04:26:37.000000000 -0400
@@ -334,8 +334,11 @@ int of_phy_register_fixed_link(struct de
 		status.link = 1;
 		status.duplex = of_property_read_bool(fixed_link_node,
 						      "full-duplex");
-		if (of_property_read_u32(fixed_link_node, "speed", &status.speed))
+		if (of_property_read_u32(fixed_link_node, "speed",
+					 &status.speed)) {
+			of_node_put(fixed_link_node);
 			return -EINVAL;
+		}
 		status.pause = of_property_read_bool(fixed_link_node, "pause");
 		status.asym_pause = of_property_read_bool(fixed_link_node,
 							  "asym-pause");
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/pci/pci-sysfs.c linux-libre-4.4.223-gnu/drivers/pci/pci-sysfs.c
--- linux-libre-4.4.222-gnu/drivers/pci/pci-sysfs.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/pci/pci-sysfs.c	2020-05-10 04:26:37.000000000 -0400
@@ -1027,6 +1027,9 @@ static int pci_mmap_resource(struct kobj
 	if (i >= PCI_ROM_RESOURCE)
 		return -ENODEV;
 
+	if (res->flags & IORESOURCE_MEM && iomem_is_exclusive(res->start))
+		return -EINVAL;
+
 	if (!pci_mmap_fits(pdev, i, vma, PCI_MMAP_SYSFS)) {
 		WARN(1, "process \"%s\" tried to map 0x%08lx bytes at page 0x%08lx on %s BAR %d (start 0x%16Lx, size 0x%16Lx)\n",
 			current->comm, vma->vm_end-vma->vm_start, vma->vm_pgoff,
@@ -1043,10 +1046,6 @@ static int pci_mmap_resource(struct kobj
 	pci_resource_to_user(pdev, i, res, &start, &end);
 	vma->vm_pgoff += start >> PAGE_SHIFT;
 	mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io;
-
-	if (res->flags & IORESOURCE_MEM && iomem_is_exclusive(start))
-		return -EINVAL;
-
 	return pci_mmap_page_range(pdev, vma, mmap_type, write_combine);
 }
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/pinctrl/bcm/pinctrl-bcm2835.c linux-libre-4.4.223-gnu/drivers/pinctrl/bcm/pinctrl-bcm2835.c
--- linux-libre-4.4.222-gnu/drivers/pinctrl/bcm/pinctrl-bcm2835.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/pinctrl/bcm/pinctrl-bcm2835.c	2020-05-10 04:26:37.000000000 -0400
@@ -795,7 +795,7 @@ static int bcm2835_pctl_dt_node_to_map(s
 	return 0;
 
 out:
-	kfree(maps);
+	bcm2835_pctl_dt_free_map(pctldev, maps, num_pins * maps_per_pin);
 	return err;
 }
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/pinctrl/pinctrl-tegra.c linux-libre-4.4.223-gnu/drivers/pinctrl/pinctrl-tegra.c
--- linux-libre-4.4.222-gnu/drivers/pinctrl/pinctrl-tegra.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/pinctrl/pinctrl-tegra.c	2020-05-10 04:26:37.000000000 -0400
@@ -418,7 +418,7 @@ static int tegra_pinconf_reg(struct tegr
 		return -ENOTSUPP;
 	}
 
-	if (*reg < 0 || *bit > 31) {
+	if (*reg < 0 || *bit < 0)  {
 		if (report_err) {
 			const char *prop = "unknown";
 			int i;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/power/bq27xxx_battery.c linux-libre-4.4.223-gnu/drivers/power/bq27xxx_battery.c
--- linux-libre-4.4.222-gnu/drivers/power/bq27xxx_battery.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/power/bq27xxx_battery.c	2020-05-10 04:26:37.000000000 -0400
@@ -198,10 +198,10 @@ static u8 bq27500_regs[] = {
 	INVALID_REG_ADDR,	/* TTECP - NA	*/
 	0x0c,	/* NAC		*/
 	0x12,	/* LMD(FCC)	*/
-	0x1e,	/* CYCT		*/
+	0x2a,	/* CYCT		*/
 	INVALID_REG_ADDR,	/* AE - NA	*/
-	0x20,	/* SOC(RSOC)	*/
-	0x2e,	/* DCAP(ILMD)	*/
+	0x2c,	/* SOC(RSOC)	*/
+	0x3c,	/* DCAP(ILMD)	*/
 	INVALID_REG_ADDR,	/* AP - NA	*/
 };
 
@@ -242,7 +242,7 @@ static u8 bq27541_regs[] = {
 	INVALID_REG_ADDR,	/* AE - NA	*/
 	0x2c,	/* SOC(RSOC)	*/
 	0x3c,	/* DCAP		*/
-	0x76,	/* AP		*/
+	0x24,	/* AP		*/
 };
 
 static u8 bq27545_regs[] = {
@@ -471,7 +471,10 @@ static int bq27xxx_battery_read_soc(stru
 {
 	int soc;
 
-	soc = bq27xxx_read(di, BQ27XXX_REG_SOC, false);
+	if (di->chip == BQ27000 || di->chip == BQ27010)
+		soc = bq27xxx_read(di, BQ27XXX_REG_SOC, true);
+	else
+		soc = bq27xxx_read(di, BQ27XXX_REG_SOC, false);
 
 	if (soc < 0)
 		dev_dbg(di->dev, "error reading State-of-Charge\n");
@@ -536,7 +539,10 @@ static int bq27xxx_battery_read_dcap(str
 {
 	int dcap;
 
-	dcap = bq27xxx_read(di, BQ27XXX_REG_DCAP, false);
+	if (di->chip == BQ27000 || di->chip == BQ27010)
+		dcap = bq27xxx_read(di, BQ27XXX_REG_DCAP, true);
+	else
+		dcap = bq27xxx_read(di, BQ27XXX_REG_DCAP, false);
 
 	if (dcap < 0) {
 		dev_dbg(di->dev, "error reading initial last measured discharge\n");
@@ -544,7 +550,7 @@ static int bq27xxx_battery_read_dcap(str
 	}
 
 	if (di->chip == BQ27000 || di->chip == BQ27010)
-		dcap *= BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
+		dcap = (dcap << 8) * BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
 	else
 		dcap *= 1000;
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/power/ipaq_micro_battery.c linux-libre-4.4.223-gnu/drivers/power/ipaq_micro_battery.c
--- linux-libre-4.4.222-gnu/drivers/power/ipaq_micro_battery.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/power/ipaq_micro_battery.c	2020-05-10 04:26:37.000000000 -0400
@@ -261,7 +261,7 @@ static int micro_batt_probe(struct platf
 	return 0;
 
 ac_err:
-	power_supply_unregister(micro_ac_power);
+	power_supply_unregister(micro_batt_power);
 batt_err:
 	cancel_delayed_work_sync(&mb->update);
 	destroy_workqueue(mb->wq);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/power/test_power.c linux-libre-4.4.223-gnu/drivers/power/test_power.c
--- linux-libre-4.4.222-gnu/drivers/power/test_power.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/power/test_power.c	2020-05-10 04:26:37.000000000 -0400
@@ -301,6 +301,8 @@ static int map_get_value(struct battery_
 	buf[MAX_KEYLENGTH-1] = '\0';
 
 	cr = strnlen(buf, MAX_KEYLENGTH) - 1;
+	if (cr < 0)
+		return def_val;
 	if (buf[cr] == '\n')
 		buf[cr] = '\0';
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/power/tps65217_charger.c linux-libre-4.4.223-gnu/drivers/power/tps65217_charger.c
--- linux-libre-4.4.222-gnu/drivers/power/tps65217_charger.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/power/tps65217_charger.c	2020-05-10 04:26:37.000000000 -0400
@@ -197,6 +197,7 @@ static int tps65217_charger_probe(struct
 {
 	struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent);
 	struct tps65217_charger *charger;
+	struct power_supply_config cfg = {};
 	int ret;
 
 	dev_dbg(&pdev->dev, "%s\n", __func__);
@@ -209,9 +210,12 @@ static int tps65217_charger_probe(struct
 	charger->tps = tps;
 	charger->dev = &pdev->dev;
 
+	cfg.of_node = pdev->dev.of_node;
+	cfg.drv_data = charger;
+
 	charger->ac = devm_power_supply_register(&pdev->dev,
 						 &tps65217_charger_desc,
-						 NULL);
+						 &cfg);
 	if (IS_ERR(charger->ac)) {
 		dev_err(&pdev->dev, "failed: power supply register\n");
 		return PTR_ERR(charger->ac);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/regulator/core.c linux-libre-4.4.223-gnu/drivers/regulator/core.c
--- linux-libre-4.4.222-gnu/drivers/regulator/core.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/regulator/core.c	2020-05-10 04:26:37.000000000 -0400
@@ -1057,18 +1057,18 @@ static int set_machine_constraints(struc
 
 	ret = machine_constraints_voltage(rdev, rdev->constraints);
 	if (ret != 0)
-		goto out;
+		return ret;
 
 	ret = machine_constraints_current(rdev, rdev->constraints);
 	if (ret != 0)
-		goto out;
+		return ret;
 
 	if (rdev->constraints->ilim_uA && ops->set_input_current_limit) {
 		ret = ops->set_input_current_limit(rdev,
 						   rdev->constraints->ilim_uA);
 		if (ret < 0) {
 			rdev_err(rdev, "failed to set input limit\n");
-			goto out;
+			return ret;
 		}
 	}
 
@@ -1077,21 +1077,20 @@ static int set_machine_constraints(struc
 		ret = suspend_prepare(rdev, rdev->constraints->initial_state);
 		if (ret < 0) {
 			rdev_err(rdev, "failed to set suspend state\n");
-			goto out;
+			return ret;
 		}
 	}
 
 	if (rdev->constraints->initial_mode) {
 		if (!ops->set_mode) {
 			rdev_err(rdev, "no set_mode operation\n");
-			ret = -EINVAL;
-			goto out;
+			return -EINVAL;
 		}
 
 		ret = ops->set_mode(rdev, rdev->constraints->initial_mode);
 		if (ret < 0) {
 			rdev_err(rdev, "failed to set initial mode: %d\n", ret);
-			goto out;
+			return ret;
 		}
 	}
 
@@ -1102,7 +1101,7 @@ static int set_machine_constraints(struc
 		ret = _regulator_do_enable(rdev);
 		if (ret < 0 && ret != -EINVAL) {
 			rdev_err(rdev, "failed to enable\n");
-			goto out;
+			return ret;
 		}
 	}
 
@@ -1111,7 +1110,7 @@ static int set_machine_constraints(struc
 		ret = ops->set_ramp_delay(rdev, rdev->constraints->ramp_delay);
 		if (ret < 0) {
 			rdev_err(rdev, "failed to set ramp_delay\n");
-			goto out;
+			return ret;
 		}
 	}
 
@@ -1119,7 +1118,7 @@ static int set_machine_constraints(struc
 		ret = ops->set_pull_down(rdev);
 		if (ret < 0) {
 			rdev_err(rdev, "failed to set pull down\n");
-			goto out;
+			return ret;
 		}
 	}
 
@@ -1127,7 +1126,7 @@ static int set_machine_constraints(struc
 		ret = ops->set_soft_start(rdev);
 		if (ret < 0) {
 			rdev_err(rdev, "failed to set soft start\n");
-			goto out;
+			return ret;
 		}
 	}
 
@@ -1136,16 +1135,12 @@ static int set_machine_constraints(struc
 		ret = ops->set_over_current_protection(rdev);
 		if (ret < 0) {
 			rdev_err(rdev, "failed to set over current protection\n");
-			goto out;
+			return ret;
 		}
 	}
 
 	print_constraints(rdev);
 	return 0;
-out:
-	kfree(rdev->constraints);
-	rdev->constraints = NULL;
-	return ret;
 }
 
 /**
@@ -3983,7 +3978,7 @@ unset_supplies:
 
 scrub:
 	regulator_ena_gpio_free(rdev);
-	kfree(rdev->constraints);
+
 wash:
 	device_unregister(&rdev->dev);
 	/* device core frees rdev */
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/scsi/cxgbi/libcxgbi.c linux-libre-4.4.223-gnu/drivers/scsi/cxgbi/libcxgbi.c
--- linux-libre-4.4.222-gnu/drivers/scsi/cxgbi/libcxgbi.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/scsi/cxgbi/libcxgbi.c	2020-05-10 04:26:37.000000000 -0400
@@ -692,6 +692,7 @@ static struct rt6_info *find_route_ipv6(
 {
 	struct flowi6 fl;
 
+	memset(&fl, 0, sizeof(fl));
 	if (saddr)
 		memcpy(&fl.saddr, saddr, sizeof(struct in6_addr));
 	if (daddr)
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/staging/media/lirc/lirc_imon.c linux-libre-4.4.223-gnu/drivers/staging/media/lirc/lirc_imon.c
--- linux-libre-4.4.222-gnu/drivers/staging/media/lirc/lirc_imon.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/staging/media/lirc/lirc_imon.c	2020-05-10 04:26:37.000000000 -0400
@@ -885,12 +885,14 @@ static int imon_probe(struct usb_interfa
 		vendor, product, ifnum, usbdev->bus->busnum, usbdev->devnum);
 
 	/* Everything went fine. Just unlock and return retval (with is 0) */
+	mutex_unlock(&context->ctx_lock);
 	goto driver_unlock;
 
 unregister_lirc:
 	lirc_unregister_driver(driver->minor);
 
 free_tx_urb:
+	mutex_unlock(&context->ctx_lock);
 	usb_free_urb(tx_urb);
 
 free_rx_urb:
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/staging/rtl8192u/r8192U_core.c linux-libre-4.4.223-gnu/drivers/staging/rtl8192u/r8192U_core.c
--- linux-libre-4.4.222-gnu/drivers/staging/rtl8192u/r8192U_core.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/staging/rtl8192u/r8192U_core.c	2020-05-10 04:26:37.000000000 -0400
@@ -1050,7 +1050,7 @@ static void rtl8192_hard_data_xmit(struc
 
 	spin_lock_irqsave(&priv->tx_lock, flags);
 
-	memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev));
+	*(struct net_device **)(skb->cb) = dev;
 	tcb_desc->bTxEnableFwCalcDur = 1;
 	skb_push(skb, priv->ieee80211->tx_headroom);
 	ret = rtl8192_tx(dev, skb);
@@ -1092,7 +1092,7 @@ static int rtl8192_hard_start_xmit(struc
 static void rtl8192_tx_isr(struct urb *tx_urb)
 {
 	struct sk_buff *skb = (struct sk_buff *)tx_urb->context;
-	struct net_device *dev = (struct net_device *)(skb->cb);
+	struct net_device *dev = *(struct net_device **)(skb->cb);
 	struct r8192_priv *priv = NULL;
 	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
 	u8  queue_index = tcb_desc->queue_index;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/target/target_core_configfs.c linux-libre-4.4.223-gnu/drivers/target/target_core_configfs.c
--- linux-libre-4.4.222-gnu/drivers/target/target_core_configfs.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/target/target_core_configfs.c	2020-05-10 04:26:37.000000000 -0400
@@ -1980,14 +1980,14 @@ static ssize_t target_dev_lba_map_store(
 	struct se_device *dev = to_device(item);
 	struct t10_alua_lba_map *lba_map = NULL;
 	struct list_head lba_list;
-	char *map_entries, *ptr;
+	char *map_entries, *orig, *ptr;
 	char state;
 	int pg_num = -1, pg;
 	int ret = 0, num = 0, pg_id, alua_state;
 	unsigned long start_lba = -1, end_lba = -1;
 	unsigned long segment_size = -1, segment_mult = -1;
 
-	map_entries = kstrdup(page, GFP_KERNEL);
+	orig = map_entries = kstrdup(page, GFP_KERNEL);
 	if (!map_entries)
 		return -ENOMEM;
 
@@ -2085,7 +2085,7 @@ out:
 	} else
 		core_alua_set_lba_map(dev, &lba_list,
 				      segment_size, segment_mult);
-	kfree(map_entries);
+	kfree(orig);
 	return count;
 }
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/tty/serial/msm_serial.c linux-libre-4.4.223-gnu/drivers/tty/serial/msm_serial.c
--- linux-libre-4.4.222-gnu/drivers/tty/serial/msm_serial.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/tty/serial/msm_serial.c	2020-05-10 04:26:37.000000000 -0400
@@ -872,37 +872,72 @@ struct msm_baud_map {
 };
 
 static const struct msm_baud_map *
-msm_find_best_baud(struct uart_port *port, unsigned int baud)
+msm_find_best_baud(struct uart_port *port, unsigned int baud,
+		   unsigned long *rate)
 {
-	unsigned int i, divisor;
-	const struct msm_baud_map *entry;
+	struct msm_port *msm_port = UART_TO_MSM(port);
+	unsigned int divisor, result;
+	unsigned long target, old, best_rate = 0, diff, best_diff = ULONG_MAX;
+	const struct msm_baud_map *entry, *end, *best;
 	static const struct msm_baud_map table[] = {
-		{ 1536, 0x00,  1 },
-		{  768, 0x11,  1 },
-		{  384, 0x22,  1 },
-		{  192, 0x33,  1 },
-		{   96, 0x44,  1 },
-		{   48, 0x55,  1 },
-		{   32, 0x66,  1 },
-		{   24, 0x77,  1 },
-		{   16, 0x88,  1 },
-		{   12, 0x99,  6 },
-		{    8, 0xaa,  6 },
-		{    6, 0xbb,  6 },
-		{    4, 0xcc,  6 },
-		{    3, 0xdd,  8 },
-		{    2, 0xee, 16 },
 		{    1, 0xff, 31 },
-		{    0, 0xff, 31 },
+		{    2, 0xee, 16 },
+		{    3, 0xdd,  8 },
+		{    4, 0xcc,  6 },
+		{    6, 0xbb,  6 },
+		{    8, 0xaa,  6 },
+		{   12, 0x99,  6 },
+		{   16, 0x88,  1 },
+		{   24, 0x77,  1 },
+		{   32, 0x66,  1 },
+		{   48, 0x55,  1 },
+		{   96, 0x44,  1 },
+		{  192, 0x33,  1 },
+		{  384, 0x22,  1 },
+		{  768, 0x11,  1 },
+		{ 1536, 0x00,  1 },
 	};
 
-	divisor = uart_get_divisor(port, baud);
+	best = table; /* Default to smallest divider */
+	target = clk_round_rate(msm_port->clk, 16 * baud);
+	divisor = DIV_ROUND_CLOSEST(target, 16 * baud);
 
-	for (i = 0, entry = table; i < ARRAY_SIZE(table); i++, entry++)
-		if (entry->divisor <= divisor)
-			break;
+	end = table + ARRAY_SIZE(table);
+	entry = table;
+	while (entry < end) {
+		if (entry->divisor <= divisor) {
+			result = target / entry->divisor / 16;
+			diff = abs(result - baud);
 
-	return entry; /* Default to smallest divider */
+			/* Keep track of best entry */
+			if (diff < best_diff) {
+				best_diff = diff;
+				best = entry;
+				best_rate = target;
+			}
+
+			if (result == baud)
+				break;
+		} else if (entry->divisor > divisor) {
+			old = target;
+			target = clk_round_rate(msm_port->clk, old + 1);
+			/*
+			 * The rate didn't get any faster so we can't do
+			 * better at dividing it down
+			 */
+			if (target == old)
+				break;
+
+			/* Start the divisor search over at this new rate */
+			entry = table;
+			divisor = DIV_ROUND_CLOSEST(target, 16 * baud);
+			continue;
+		}
+		entry++;
+	}
+
+	*rate = best_rate;
+	return best;
 }
 
 static int msm_set_baud_rate(struct uart_port *port, unsigned int baud,
@@ -911,22 +946,20 @@ static int msm_set_baud_rate(struct uart
 	unsigned int rxstale, watermark, mask;
 	struct msm_port *msm_port = UART_TO_MSM(port);
 	const struct msm_baud_map *entry;
-	unsigned long flags;
-
-	entry = msm_find_best_baud(port, baud);
-
-	msm_write(port, entry->code, UART_CSR);
-
-	if (baud > 460800)
-		port->uartclk = baud * 16;
+	unsigned long flags, rate;
 
 	flags = *saved_flags;
 	spin_unlock_irqrestore(&port->lock, flags);
 
-	clk_set_rate(msm_port->clk, port->uartclk);
+	entry = msm_find_best_baud(port, baud, &rate);
+	clk_set_rate(msm_port->clk, rate);
+	baud = rate / 16 / entry->divisor;
 
 	spin_lock_irqsave(&port->lock, flags);
 	*saved_flags = flags;
+	port->uartclk = rate;
+
+	msm_write(port, entry->code, UART_CSR);
 
 	/* RX stale watermark */
 	rxstale = entry->rxstale;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/tty/serial/samsung.c linux-libre-4.4.223-gnu/drivers/tty/serial/samsung.c
--- linux-libre-4.4.222-gnu/drivers/tty/serial/samsung.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/tty/serial/samsung.c	2020-05-10 04:26:37.000000000 -0400
@@ -1841,8 +1841,6 @@ static int s3c24xx_serial_probe(struct p
 	ourport->min_dma_size = max_t(int, ourport->port.fifosize,
 				    dma_get_cache_alignment());
 
-	probe_index++;
-
 	dbg("%s: initialising port %p...\n", __func__, ourport);
 
 	ret = s3c24xx_serial_init_port(ourport, pdev);
@@ -1872,6 +1870,8 @@ static int s3c24xx_serial_probe(struct p
 	if (ret < 0)
 		dev_err(&pdev->dev, "failed to add cpufreq notifier\n");
 
+	probe_index++;
+
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/usb/gadget/function/f_acm.c linux-libre-4.4.223-gnu/drivers/usb/gadget/function/f_acm.c
--- linux-libre-4.4.222-gnu/drivers/usb/gadget/function/f_acm.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/usb/gadget/function/f_acm.c	2020-05-10 04:26:37.000000000 -0400
@@ -779,10 +779,10 @@ static ssize_t f_acm_port_num_show(struc
 	return sprintf(page, "%u\n", to_f_serial_opts(item)->port_num);
 }
 
-CONFIGFS_ATTR_RO(f_acm_port_, num);
+CONFIGFS_ATTR_RO(f_acm_, port_num);
 
 static struct configfs_attribute *acm_attrs[] = {
-	&f_acm_port_attr_num,
+	&f_acm_attr_port_num,
 	NULL,
 };
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/usb/gadget/udc/pch_udc.c linux-libre-4.4.223-gnu/drivers/usb/gadget/udc/pch_udc.c
--- linux-libre-4.4.222-gnu/drivers/usb/gadget/udc/pch_udc.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/usb/gadget/udc/pch_udc.c	2020-05-10 04:26:37.000000000 -0400
@@ -1488,11 +1488,11 @@ static void complete_req(struct pch_udc_
 		req->dma_mapped = 0;
 	}
 	ep->halted = 1;
-	spin_lock(&dev->lock);
+	spin_unlock(&dev->lock);
 	if (!ep->in)
 		pch_udc_ep_clear_rrdy(ep);
 	usb_gadget_giveback_request(&ep->ep, &req->req);
-	spin_unlock(&dev->lock);
+	spin_lock(&dev->lock);
 	ep->halted = halted;
 }
 
@@ -1731,14 +1731,12 @@ static int pch_udc_pcd_ep_enable(struct
 static int pch_udc_pcd_ep_disable(struct usb_ep *usbep)
 {
 	struct pch_udc_ep	*ep;
-	struct pch_udc_dev	*dev;
 	unsigned long	iflags;
 
 	if (!usbep)
 		return -EINVAL;
 
 	ep = container_of(usbep, struct pch_udc_ep, ep);
-	dev = ep->dev;
 	if ((usbep->name == ep0_string) || !ep->ep.desc)
 		return -EINVAL;
 
@@ -1769,12 +1767,10 @@ static struct usb_request *pch_udc_alloc
 	struct pch_udc_request		*req;
 	struct pch_udc_ep		*ep;
 	struct pch_udc_data_dma_desc	*dma_desc;
-	struct pch_udc_dev		*dev;
 
 	if (!usbep)
 		return NULL;
 	ep = container_of(usbep, struct pch_udc_ep, ep);
-	dev = ep->dev;
 	req = kzalloc(sizeof *req, gfp);
 	if (!req)
 		return NULL;
@@ -1947,12 +1943,10 @@ static int pch_udc_pcd_dequeue(struct us
 {
 	struct pch_udc_ep	*ep;
 	struct pch_udc_request	*req;
-	struct pch_udc_dev	*dev;
 	unsigned long		flags;
 	int ret = -EINVAL;
 
 	ep = container_of(usbep, struct pch_udc_ep, ep);
-	dev = ep->dev;
 	if (!usbep || !usbreq || (!ep->ep.desc && ep->num))
 		return ret;
 	req = container_of(usbreq, struct pch_udc_request, req);
@@ -1984,14 +1978,12 @@ static int pch_udc_pcd_dequeue(struct us
 static int pch_udc_pcd_set_halt(struct usb_ep *usbep, int halt)
 {
 	struct pch_udc_ep	*ep;
-	struct pch_udc_dev	*dev;
 	unsigned long iflags;
 	int ret;
 
 	if (!usbep)
 		return -EINVAL;
 	ep = container_of(usbep, struct pch_udc_ep, ep);
-	dev = ep->dev;
 	if (!ep->ep.desc && !ep->num)
 		return -EINVAL;
 	if (!ep->dev->driver || (ep->dev->gadget.speed == USB_SPEED_UNKNOWN))
@@ -2029,14 +2021,12 @@ static int pch_udc_pcd_set_halt(struct u
 static int pch_udc_pcd_set_wedge(struct usb_ep *usbep)
 {
 	struct pch_udc_ep	*ep;
-	struct pch_udc_dev	*dev;
 	unsigned long iflags;
 	int ret;
 
 	if (!usbep)
 		return -EINVAL;
 	ep = container_of(usbep, struct pch_udc_ep, ep);
-	dev = ep->dev;
 	if (!ep->ep.desc && !ep->num)
 		return -EINVAL;
 	if (!ep->dev->driver || (ep->dev->gadget.speed == USB_SPEED_UNKNOWN))
@@ -2593,9 +2583,9 @@ static void pch_udc_svc_ur_interrupt(str
 		empty_req_queue(ep);
 	}
 	if (dev->driver) {
-		spin_lock(&dev->lock);
-		usb_gadget_udc_reset(&dev->gadget, dev->driver);
 		spin_unlock(&dev->lock);
+		usb_gadget_udc_reset(&dev->gadget, dev->driver);
+		spin_lock(&dev->lock);
 	}
 }
 
@@ -2646,7 +2636,7 @@ static void pch_udc_svc_enum_interrupt(s
 static void pch_udc_svc_intf_interrupt(struct pch_udc_dev *dev)
 {
 	u32 reg, dev_stat = 0;
-	int i, ret;
+	int i;
 
 	dev_stat = pch_udc_read_device_status(dev);
 	dev->cfg_data.cur_intf = (dev_stat & UDC_DEVSTS_INTF_MASK) >>
@@ -2674,9 +2664,9 @@ static void pch_udc_svc_intf_interrupt(s
 		dev->ep[i].halted = 0;
 	}
 	dev->stall = 0;
-	spin_lock(&dev->lock);
-	ret = dev->driver->setup(&dev->gadget, &dev->setup_data);
 	spin_unlock(&dev->lock);
+	dev->driver->setup(&dev->gadget, &dev->setup_data);
+	spin_lock(&dev->lock);
 }
 
 /**
@@ -2686,7 +2676,7 @@ static void pch_udc_svc_intf_interrupt(s
  */
 static void pch_udc_svc_cfg_interrupt(struct pch_udc_dev *dev)
 {
-	int i, ret;
+	int i;
 	u32 reg, dev_stat = 0;
 
 	dev_stat = pch_udc_read_device_status(dev);
@@ -2711,9 +2701,9 @@ static void pch_udc_svc_cfg_interrupt(st
 	dev->stall = 0;
 
 	/* call gadget zero with setup data received */
-	spin_lock(&dev->lock);
-	ret = dev->driver->setup(&dev->gadget, &dev->setup_data);
 	spin_unlock(&dev->lock);
+	dev->driver->setup(&dev->gadget, &dev->setup_data);
+	spin_lock(&dev->lock);
 }
 
 /**
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/usb/gadget/udc/udc-core.c linux-libre-4.4.223-gnu/drivers/usb/gadget/udc/udc-core.c
--- linux-libre-4.4.222-gnu/drivers/usb/gadget/udc/udc-core.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/usb/gadget/udc/udc-core.c	2020-05-10 04:26:37.000000000 -0400
@@ -97,7 +97,7 @@ void usb_gadget_unmap_request(struct usb
 		return;
 
 	if (req->num_mapped_sgs) {
-		dma_unmap_sg(gadget->dev.parent, req->sg, req->num_mapped_sgs,
+		dma_unmap_sg(gadget->dev.parent, req->sg, req->num_sgs,
 				is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
 
 		req->num_mapped_sgs = 0;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/vfio/pci/vfio_pci_config.c linux-libre-4.4.223-gnu/drivers/vfio/pci/vfio_pci_config.c
--- linux-libre-4.4.222-gnu/drivers/vfio/pci/vfio_pci_config.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/vfio/pci/vfio_pci_config.c	2020-05-10 04:26:37.000000000 -0400
@@ -698,7 +698,8 @@ static int vfio_vpd_config_write(struct
 		if (pci_write_vpd(pdev, addr & ~PCI_VPD_ADDR_F, 4, &data) != 4)
 			return count;
 	} else {
-		if (pci_read_vpd(pdev, addr, 4, &data) != 4)
+		data = 0;
+		if (pci_read_vpd(pdev, addr, 4, &data) < 0)
 			return count;
 		*pdata = cpu_to_le32(data);
 	}
diff -druNp --no-dereference linux-libre-4.4.222-gnu/drivers/vfio/platform/reset/vfio_platform_amdxgbe.c linux-libre-4.4.223-gnu/drivers/vfio/platform/reset/vfio_platform_amdxgbe.c
--- linux-libre-4.4.222-gnu/drivers/vfio/platform/reset/vfio_platform_amdxgbe.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/drivers/vfio/platform/reset/vfio_platform_amdxgbe.c	2020-05-10 04:26:37.000000000 -0400
@@ -110,7 +110,7 @@ int vfio_platform_amdxgbe_reset(struct v
 	usleep_range(10, 15);
 
 	count = 2000;
-	while (count-- && (ioread32(xgmac_regs->ioaddr + DMA_MR) & 1))
+	while (--count && (ioread32(xgmac_regs->ioaddr + DMA_MR) & 1))
 		usleep_range(500, 600);
 
 	if (!count)
diff -druNp --no-dereference linux-libre-4.4.222-gnu/fs/btrfs/disk-io.c linux-libre-4.4.223-gnu/fs/btrfs/disk-io.c
--- linux-libre-4.4.222-gnu/fs/btrfs/disk-io.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/fs/btrfs/disk-io.c	2020-05-10 04:26:37.000000000 -0400
@@ -1750,7 +1750,7 @@ static int cleaner_kthread(void *arg)
 		 */
 		btrfs_delete_unused_bgs(root->fs_info);
 sleep:
-		if (!try_to_freeze() && !again) {
+		if (!again) {
 			set_current_state(TASK_INTERRUPTIBLE);
 			if (!kthread_should_stop())
 				schedule();
diff -druNp --no-dereference linux-libre-4.4.222-gnu/fs/btrfs/extent-tree.c linux-libre-4.4.223-gnu/fs/btrfs/extent-tree.c
--- linux-libre-4.4.222-gnu/fs/btrfs/extent-tree.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/fs/btrfs/extent-tree.c	2020-05-10 04:26:37.000000000 -0400
@@ -10688,7 +10688,7 @@ int btrfs_init_space_info(struct btrfs_f
 
 	disk_super = fs_info->super_copy;
 	if (!btrfs_super_root(disk_super))
-		return 1;
+		return -EINVAL;
 
 	features = btrfs_super_incompat_flags(disk_super);
 	if (features & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS)
diff -druNp --no-dereference linux-libre-4.4.222-gnu/fs/cifs/connect.c linux-libre-4.4.223-gnu/fs/cifs/connect.c
--- linux-libre-4.4.222-gnu/fs/cifs/connect.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/fs/cifs/connect.c	2020-05-10 04:26:37.000000000 -0400
@@ -338,8 +338,10 @@ static int reconn_set_ipaddr(struct TCP_
 		return rc;
 	}
 
+	spin_lock(&cifs_tcp_ses_lock);
 	rc = cifs_convert_address((struct sockaddr *)&server->dstaddr, ipaddr,
 				  strlen(ipaddr));
+	spin_unlock(&cifs_tcp_ses_lock);
 	kfree(ipaddr);
 
 	return !rc ? -1 : 0;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/fs/gfs2/file.c linux-libre-4.4.223-gnu/fs/gfs2/file.c
--- linux-libre-4.4.222-gnu/fs/gfs2/file.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/fs/gfs2/file.c	2020-05-10 04:26:37.000000000 -0400
@@ -1035,7 +1035,10 @@ static int do_flock(struct file *file, i
 		if (fl_gh->gh_state == state)
 			goto out;
 		locks_lock_file_wait(file,
-				     &(struct file_lock){.fl_type = F_UNLCK});
+				     &(struct file_lock) {
+					     .fl_type = F_UNLCK,
+					     .fl_flags = FL_FLOCK
+				     });
 		gfs2_glock_dq(fl_gh);
 		gfs2_holder_reinit(state, flags, fl_gh);
 	} else {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/fs/nfs/nfs4proc.c linux-libre-4.4.223-gnu/fs/nfs/nfs4proc.c
--- linux-libre-4.4.222-gnu/fs/nfs/nfs4proc.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/fs/nfs/nfs4proc.c	2020-05-10 04:26:37.000000000 -0400
@@ -6054,6 +6054,7 @@ static int nfs41_lock_expired(struct nfs
 static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
 {
 	struct nfs_inode *nfsi = NFS_I(state->inode);
+	struct nfs4_state_owner *sp = state->owner;
 	unsigned char fl_flags = request->fl_flags;
 	int status = -ENOLCK;
 
@@ -6068,6 +6069,7 @@ static int _nfs4_proc_setlk(struct nfs4_
 	status = do_vfs_lock(state->inode, request);
 	if (status < 0)
 		goto out;
+	mutex_lock(&sp->so_delegreturn_mutex);
 	down_read(&nfsi->rwsem);
 	if (test_bit(NFS_DELEGATED_STATE, &state->flags)) {
 		/* Yes: cache locks! */
@@ -6075,9 +6077,11 @@ static int _nfs4_proc_setlk(struct nfs4_
 		request->fl_flags = fl_flags & ~FL_SLEEP;
 		status = do_vfs_lock(state->inode, request);
 		up_read(&nfsi->rwsem);
+		mutex_unlock(&sp->so_delegreturn_mutex);
 		goto out;
 	}
 	up_read(&nfsi->rwsem);
+	mutex_unlock(&sp->so_delegreturn_mutex);
 	status = _nfs4_do_setlk(state, cmd, request, NFS_LOCK_NEW);
 out:
 	request->fl_flags = fl_flags;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/include/asm-generic/preempt.h linux-libre-4.4.223-gnu/include/asm-generic/preempt.h
--- linux-libre-4.4.222-gnu/include/asm-generic/preempt.h	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/include/asm-generic/preempt.h	2020-05-10 04:26:37.000000000 -0400
@@ -7,10 +7,10 @@
 
 static __always_inline int preempt_count(void)
 {
-	return current_thread_info()->preempt_count;
+	return READ_ONCE(current_thread_info()->preempt_count);
 }
 
-static __always_inline int *preempt_count_ptr(void)
+static __always_inline volatile int *preempt_count_ptr(void)
 {
 	return &current_thread_info()->preempt_count;
 }
diff -druNp --no-dereference linux-libre-4.4.222-gnu/include/linux/cpufreq.h linux-libre-4.4.223-gnu/include/linux/cpufreq.h
--- linux-libre-4.4.222-gnu/include/linux/cpufreq.h	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/include/linux/cpufreq.h	2020-05-10 04:26:37.000000000 -0400
@@ -100,10 +100,6 @@ struct cpufreq_policy {
 	 * - Any routine that will write to the policy structure and/or may take away
 	 *   the policy altogether (eg. CPU hotplug), will hold this lock in write
 	 *   mode before doing so.
-	 *
-	 * Additional rules:
-	 * - Lock should not be held across
-	 *     __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT);
 	 */
 	struct rw_semaphore	rwsem;
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/include/linux/ieee80211.h linux-libre-4.4.223-gnu/include/linux/ieee80211.h
--- linux-libre-4.4.222-gnu/include/linux/ieee80211.h	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/include/linux/ieee80211.h	2020-05-10 04:26:37.000000000 -0400
@@ -607,6 +607,15 @@ static inline bool ieee80211_is_qos_null
 }
 
 /**
+ * ieee80211_is_any_nullfunc - check if frame is regular or QoS nullfunc frame
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline bool ieee80211_is_any_nullfunc(__le16 fc)
+{
+	return (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc));
+}
+
+/**
  * ieee80211_is_bufferable_mmpdu - check if frame is bufferable MMPDU
  * @fc: frame control field in little-endian byteorder
  */
diff -druNp --no-dereference linux-libre-4.4.222-gnu/include/linux/mlx5/driver.h linux-libre-4.4.223-gnu/include/linux/mlx5/driver.h
--- linux-libre-4.4.222-gnu/include/linux/mlx5/driver.h	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/include/linux/mlx5/driver.h	2020-05-10 04:26:37.000000000 -0400
@@ -54,7 +54,7 @@ enum {
 	/* one minute for the sake of bringup. Generally, commands must always
 	 * complete and we may need to increase this timeout value
 	 */
-	MLX5_CMD_TIMEOUT_MSEC	= 7200 * 1000,
+	MLX5_CMD_TIMEOUT_MSEC	= 60 * 1000,
 	MLX5_CMD_WQ_MAX_NAME	= 32,
 };
 
@@ -566,6 +566,7 @@ struct mlx5_cmd_work_ent {
 	void		       *uout;
 	int			uout_size;
 	mlx5_cmd_cbk_t		callback;
+	struct delayed_work	cb_timeout_work;
 	void		       *context;
 	int			idx;
 	struct completion	done;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/include/linux/mlx5/qp.h linux-libre-4.4.223-gnu/include/linux/mlx5/qp.h
--- linux-libre-4.4.222-gnu/include/linux/mlx5/qp.h	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/include/linux/mlx5/qp.h	2020-05-10 04:26:37.000000000 -0400
@@ -539,6 +539,7 @@ struct mlx5_modify_qp_mbox_in {
 	__be32			optparam;
 	u8			rsvd1[4];
 	struct mlx5_qp_context	ctx;
+	u8			rsvd2[16];
 };
 
 struct mlx5_modify_qp_mbox_out {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/include/linux/mtd/nand.h linux-libre-4.4.223-gnu/include/linux/mtd/nand.h
--- linux-libre-4.4.222-gnu/include/linux/mtd/nand.h	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/include/linux/mtd/nand.h	2020-05-10 04:26:37.000000000 -0400
@@ -276,7 +276,7 @@ struct nand_onfi_params {
 	__le16 t_r;
 	__le16 t_ccs;
 	__le16 src_sync_timing_mode;
-	__le16 src_ssync_features;
+	u8 src_ssync_features;
 	__le16 clk_pin_capacitance_typ;
 	__le16 io_pin_capacitance_typ;
 	__le16 input_pin_capacitance_typ;
@@ -284,7 +284,7 @@ struct nand_onfi_params {
 	u8 driver_strength_support;
 	__le16 t_int_r;
 	__le16 t_ald;
-	u8 reserved4[7];
+	u8 reserved4[8];
 
 	/* vendor */
 	__le16 vendor_revision;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/include/linux/netdevice.h linux-libre-4.4.223-gnu/include/linux/netdevice.h
--- linux-libre-4.4.222-gnu/include/linux/netdevice.h	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/include/linux/netdevice.h	2020-05-10 04:26:37.000000000 -0400
@@ -2013,7 +2013,10 @@ struct napi_gro_cb {
 	/* Number of gro_receive callbacks this packet already went through */
 	u8 recursion_counter:4;
 
-	/* 3 bit hole */
+	/* Used in GRE, set in fou/gue_gro_receive */
+	u8	is_fou:1;
+
+	/* 2 bit hole */
 
 	/* used to support CHECKSUM_COMPLETE for tunneling protocols */
 	__wsum	csum;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/include/linux/sunrpc/msg_prot.h linux-libre-4.4.223-gnu/include/linux/sunrpc/msg_prot.h
--- linux-libre-4.4.222-gnu/include/linux/sunrpc/msg_prot.h	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/include/linux/sunrpc/msg_prot.h	2020-05-10 04:26:37.000000000 -0400
@@ -158,9 +158,9 @@ typedef __be32	rpc_fraghdr;
 
 /*
  * Note that RFC 1833 does not put any size restrictions on the
- * netid string, but all currently defined netid's fit in 4 bytes.
+ * netid string, but all currently defined netid's fit in 5 bytes.
  */
-#define RPCBIND_MAXNETIDLEN	(4u)
+#define RPCBIND_MAXNETIDLEN	(5u)
 
 /*
  * Universal addresses are introduced in RFC 1833 and further spelled
diff -druNp --no-dereference linux-libre-4.4.222-gnu/include/net/bonding.h linux-libre-4.4.223-gnu/include/net/bonding.h
--- linux-libre-4.4.222-gnu/include/net/bonding.h	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/include/net/bonding.h	2020-05-10 04:26:37.000000000 -0400
@@ -34,6 +34,9 @@
 
 #define BOND_DEFAULT_MIIMON	100
 
+#ifndef __long_aligned
+#define __long_aligned __attribute__((aligned((sizeof(long)))))
+#endif
 /*
  * Less bad way to call ioctl from within the kernel; this needs to be
  * done some other way to get the call out of interrupt context.
@@ -138,7 +141,9 @@ struct bond_params {
 	struct reciprocal_value reciprocal_packets_per_slave;
 	u16 ad_actor_sys_prio;
 	u16 ad_user_port_key;
-	u8 ad_actor_system[ETH_ALEN];
+
+	/* 2 bytes of padding : see ether_addr_equal_64bits() */
+	u8 ad_actor_system[ETH_ALEN + 2];
 };
 
 struct bond_parm_tbl {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/include/net/ip6_fib.h linux-libre-4.4.223-gnu/include/net/ip6_fib.h
--- linux-libre-4.4.222-gnu/include/net/ip6_fib.h	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/include/net/ip6_fib.h	2020-05-10 04:26:37.000000000 -0400
@@ -258,6 +258,8 @@ struct fib6_table {
 	rwlock_t		tb6_lock;
 	struct fib6_node	tb6_root;
 	struct inet_peer_base	tb6_peers;
+	unsigned int		flags;
+#define RT6_TABLE_HAS_DFLT_ROUTER	BIT(0)
 };
 
 #define RT6_TABLE_UNSPEC	RT_TABLE_UNSPEC
diff -druNp --no-dereference linux-libre-4.4.222-gnu/include/net/ip6_route.h linux-libre-4.4.223-gnu/include/net/ip6_route.h
--- linux-libre-4.4.222-gnu/include/net/ip6_route.h	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/include/net/ip6_route.h	2020-05-10 04:26:37.000000000 -0400
@@ -103,6 +103,9 @@ void fib6_force_start_gc(struct net *net
 struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
 				    const struct in6_addr *addr, bool anycast);
 
+struct rt6_info *ip6_dst_alloc(struct net *net, struct net_device *dev,
+			       int flags);
+
 /*
  *	support functions for ND
  *
diff -druNp --no-dereference linux-libre-4.4.222-gnu/include/net/ip_fib.h linux-libre-4.4.223-gnu/include/net/ip_fib.h
--- linux-libre-4.4.222-gnu/include/net/ip_fib.h	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/include/net/ip_fib.h	2020-05-10 04:26:37.000000000 -0400
@@ -112,6 +112,7 @@ struct fib_info {
 	unsigned char		fib_scope;
 	unsigned char		fib_type;
 	__be32			fib_prefsrc;
+	u32			fib_tb_id;
 	u32			fib_priority;
 	struct dst_metrics	*fib_metrics;
 #define fib_mtu fib_metrics->metrics[RTAX_MTU-1]
@@ -320,7 +321,7 @@ void fib_flush_external(struct net *net)
 /* Exported by fib_semantics.c */
 int ip_fib_check_default(__be32 gw, struct net_device *dev);
 int fib_sync_down_dev(struct net_device *dev, unsigned long event, bool force);
-int fib_sync_down_addr(struct net *net, __be32 local);
+int fib_sync_down_addr(struct net_device *dev, __be32 local);
 int fib_sync_up(struct net_device *dev, unsigned int nh_flags);
 void fib_sync_mtu(struct net_device *dev, u32 orig_mtu);
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/include/net/route.h linux-libre-4.4.223-gnu/include/net/route.h
--- linux-libre-4.4.222-gnu/include/net/route.h	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/include/net/route.h	2020-05-10 04:26:37.000000000 -0400
@@ -210,6 +210,9 @@ unsigned int inet_addr_type_dev_table(st
 void ip_rt_multicast_event(struct in_device *);
 int ip_rt_ioctl(struct net *, unsigned int cmd, void __user *arg);
 void ip_rt_get_source(u8 *src, struct sk_buff *skb, struct rtable *rt);
+struct rtable *rt_dst_alloc(struct net_device *dev,
+			     unsigned int flags, u16 type,
+			     bool nopolicy, bool noxfrm, bool will_cache);
 
 struct in_ifaddr;
 void fib_add_ifaddr(struct in_ifaddr *);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/include/net/sch_generic.h linux-libre-4.4.223-gnu/include/net/sch_generic.h
--- linux-libre-4.4.222-gnu/include/net/sch_generic.h	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/include/net/sch_generic.h	2020-05-10 04:26:37.000000000 -0400
@@ -674,9 +674,11 @@ static inline struct sk_buff *qdisc_peek
 	/* we can reuse ->gso_skb because peek isn't called for root qdiscs */
 	if (!sch->gso_skb) {
 		sch->gso_skb = sch->dequeue(sch);
-		if (sch->gso_skb)
+		if (sch->gso_skb) {
 			/* it's still part of the queue */
+			qdisc_qstats_backlog_inc(sch, sch->gso_skb);
 			sch->q.qlen++;
+		}
 	}
 
 	return sch->gso_skb;
@@ -689,6 +691,7 @@ static inline struct sk_buff *qdisc_dequ
 
 	if (skb) {
 		sch->gso_skb = NULL;
+		qdisc_qstats_backlog_dec(sch, skb);
 		sch->q.qlen--;
 	} else {
 		skb = sch->dequeue(sch);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/include/net/sock.h linux-libre-4.4.223-gnu/include/net/sock.h
--- linux-libre-4.4.222-gnu/include/net/sock.h	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/include/net/sock.h	2020-05-10 04:26:37.000000000 -0400
@@ -1204,11 +1204,13 @@ static inline void memcg_memory_allocate
 					      unsigned long amt,
 					      int *parent_status)
 {
-	page_counter_charge(&prot->memory_allocated, amt);
+	struct page_counter *counter;
 
-	if (page_counter_read(&prot->memory_allocated) >
-	    prot->memory_allocated.limit)
-		*parent_status = OVER_LIMIT;
+	if (page_counter_try_charge(&prot->memory_allocated, amt, &counter))
+		return;
+
+	page_counter_charge(&prot->memory_allocated, amt);
+	*parent_status = OVER_LIMIT;
 }
 
 static inline void memcg_memory_allocated_sub(struct cg_proto *prot,
@@ -1651,7 +1653,13 @@ static inline void sock_put(struct sock
  */
 void sock_gen_put(struct sock *sk);
 
-int sk_receive_skb(struct sock *sk, struct sk_buff *skb, const int nested);
+int __sk_receive_skb(struct sock *sk, struct sk_buff *skb, const int nested,
+		     unsigned int trim_cap);
+static inline int sk_receive_skb(struct sock *sk, struct sk_buff *skb,
+				 const int nested)
+{
+	return __sk_receive_skb(sk, skb, nested, 1);
+}
 
 static inline void sk_tx_queue_set(struct sock *sk, int tx_queue)
 {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/include/net/xfrm.h linux-libre-4.4.223-gnu/include/net/xfrm.h
--- linux-libre-4.4.222-gnu/include/net/xfrm.h	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/include/net/xfrm.h	2020-05-10 04:26:37.000000000 -0400
@@ -1551,8 +1551,10 @@ int xfrm4_tunnel_deregister(struct xfrm_
 void xfrm4_local_error(struct sk_buff *skb, u32 mtu);
 int xfrm6_extract_header(struct sk_buff *skb);
 int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb);
-int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi);
+int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi,
+		  struct ip6_tnl *t);
 int xfrm6_transport_finish(struct sk_buff *skb, int async);
+int xfrm6_rcv_tnl(struct sk_buff *skb, struct ip6_tnl *t);
 int xfrm6_rcv(struct sk_buff *skb);
 int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
 		     xfrm_address_t *saddr, u8 proto);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/kernel/bpf/syscall.c linux-libre-4.4.223-gnu/kernel/bpf/syscall.c
--- linux-libre-4.4.222-gnu/kernel/bpf/syscall.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/kernel/bpf/syscall.c	2020-05-10 04:26:37.000000000 -0400
@@ -152,7 +152,7 @@ static int map_create(union bpf_attr *at
 
 	err = bpf_map_charge_memlock(map);
 	if (err)
-		goto free_map;
+		goto free_map_nouncharge;
 
 	err = bpf_map_new_fd(map);
 	if (err < 0)
@@ -162,6 +162,8 @@ static int map_create(union bpf_attr *at
 	return err;
 
 free_map:
+	bpf_map_uncharge_memlock(map);
+free_map_nouncharge:
 	map->ops->map_free(map);
 	return err;
 }
diff -druNp --no-dereference linux-libre-4.4.222-gnu/kernel/sched/fair.c linux-libre-4.4.223-gnu/kernel/sched/fair.c
--- linux-libre-4.4.222-gnu/kernel/sched/fair.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/kernel/sched/fair.c	2020-05-10 04:26:37.000000000 -0400
@@ -2394,28 +2394,22 @@ account_entity_dequeue(struct cfs_rq *cf
 
 #ifdef CONFIG_FAIR_GROUP_SCHED
 # ifdef CONFIG_SMP
-static inline long calc_tg_weight(struct task_group *tg, struct cfs_rq *cfs_rq)
+static long calc_cfs_shares(struct cfs_rq *cfs_rq, struct task_group *tg)
 {
-	long tg_weight;
+	long tg_weight, load, shares;
 
 	/*
-	 * Use this CPU's real-time load instead of the last load contribution
-	 * as the updating of the contribution is delayed, and we will use the
-	 * the real-time load to calc the share. See update_tg_load_avg().
+	 * This really should be: cfs_rq->avg.load_avg, but instead we use
+	 * cfs_rq->load.weight, which is its upper bound. This helps ramp up
+	 * the shares for small weight interactive tasks.
 	 */
-	tg_weight = atomic_long_read(&tg->load_avg);
-	tg_weight -= cfs_rq->tg_load_avg_contrib;
-	tg_weight += cfs_rq->load.weight;
-
-	return tg_weight;
-}
+	load = scale_load_down(cfs_rq->load.weight);
 
-static long calc_cfs_shares(struct cfs_rq *cfs_rq, struct task_group *tg)
-{
-	long tg_weight, load, shares;
+	tg_weight = atomic_long_read(&tg->load_avg);
 
-	tg_weight = calc_tg_weight(tg, cfs_rq);
-	load = cfs_rq->load.weight;
+	/* Ensure tg_weight >= load */
+	tg_weight -= cfs_rq->tg_load_avg_contrib;
+	tg_weight += load;
 
 	shares = (tg->shares * load);
 	if (tg_weight)
@@ -2434,6 +2428,7 @@ static inline long calc_cfs_shares(struc
 	return tg->shares;
 }
 # endif /* CONFIG_SMP */
+
 static void reweight_entity(struct cfs_rq *cfs_rq, struct sched_entity *se,
 			    unsigned long weight)
 {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/kernel/trace/bpf_trace.c linux-libre-4.4.223-gnu/kernel/trace/bpf_trace.c
--- linux-libre-4.4.222-gnu/kernel/trace/bpf_trace.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/kernel/trace/bpf_trace.c	2020-05-10 04:26:37.000000000 -0400
@@ -206,6 +206,10 @@ static u64 bpf_perf_event_read(u64 r1, u
 	    event->pmu->count)
 		return -EINVAL;
 
+	if (unlikely(event->attr.type != PERF_TYPE_HARDWARE &&
+		     event->attr.type != PERF_TYPE_RAW))
+		return -EINVAL;
+
 	/*
 	 * we don't know if the function is run successfully by the
 	 * return value. It can be judged in other places, such as
diff -druNp --no-dereference linux-libre-4.4.222-gnu/lib/mpi/longlong.h linux-libre-4.4.223-gnu/lib/mpi/longlong.h
--- linux-libre-4.4.222-gnu/lib/mpi/longlong.h	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/lib/mpi/longlong.h	2020-05-10 04:26:37.000000000 -0400
@@ -756,22 +756,22 @@ do {									\
 do { \
 	if (__builtin_constant_p(bh) && (bh) == 0) \
 		__asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \
-		: "=r" ((USItype)(sh)), \
-		"=&r" ((USItype)(sl)) \
+		: "=r" (sh), \
+		"=&r" (sl) \
 		: "%r" ((USItype)(ah)), \
 		"%r" ((USItype)(al)), \
 		"rI" ((USItype)(bl))); \
 	else if (__builtin_constant_p(bh) && (bh) == ~(USItype) 0) \
 		__asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \
-		: "=r" ((USItype)(sh)), \
-		"=&r" ((USItype)(sl)) \
+		: "=r" (sh), \
+		"=&r" (sl) \
 		: "%r" ((USItype)(ah)), \
 		"%r" ((USItype)(al)), \
 		"rI" ((USItype)(bl))); \
 	else \
 		__asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \
-		: "=r" ((USItype)(sh)), \
-		"=&r" ((USItype)(sl)) \
+		: "=r" (sh), \
+		"=&r" (sl) \
 		: "%r" ((USItype)(ah)), \
 		"r" ((USItype)(bh)), \
 		"%r" ((USItype)(al)), \
@@ -781,36 +781,36 @@ do { \
 do { \
 	if (__builtin_constant_p(ah) && (ah) == 0) \
 		__asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \
-		: "=r" ((USItype)(sh)), \
-		"=&r" ((USItype)(sl)) \
+		: "=r" (sh), \
+		"=&r" (sl) \
 		: "r" ((USItype)(bh)), \
 		"rI" ((USItype)(al)), \
 		"r" ((USItype)(bl))); \
 	else if (__builtin_constant_p(ah) && (ah) == ~(USItype) 0) \
 		__asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \
-		: "=r" ((USItype)(sh)), \
-		"=&r" ((USItype)(sl)) \
+		: "=r" (sh), \
+		"=&r" (sl) \
 		: "r" ((USItype)(bh)), \
 		"rI" ((USItype)(al)), \
 		"r" ((USItype)(bl))); \
 	else if (__builtin_constant_p(bh) && (bh) == 0) \
 		__asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \
-		: "=r" ((USItype)(sh)), \
-		"=&r" ((USItype)(sl)) \
+		: "=r" (sh), \
+		"=&r" (sl) \
 		: "r" ((USItype)(ah)), \
 		"rI" ((USItype)(al)), \
 		"r" ((USItype)(bl))); \
 	else if (__builtin_constant_p(bh) && (bh) == ~(USItype) 0) \
 		__asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \
-		: "=r" ((USItype)(sh)), \
-		"=&r" ((USItype)(sl)) \
+		: "=r" (sh), \
+		"=&r" (sl) \
 		: "r" ((USItype)(ah)), \
 		"rI" ((USItype)(al)), \
 		"r" ((USItype)(bl))); \
 	else \
 		__asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \
-		: "=r" ((USItype)(sh)), \
-		"=&r" ((USItype)(sl)) \
+		: "=r" (sh), \
+		"=&r" (sl) \
 		: "r" ((USItype)(ah)), \
 		"r" ((USItype)(bh)), \
 		"rI" ((USItype)(al)), \
@@ -821,7 +821,7 @@ do { \
 do { \
 	USItype __m0 = (m0), __m1 = (m1); \
 	__asm__ ("mulhwu %0,%1,%2" \
-	: "=r" ((USItype) ph) \
+	: "=r" (ph) \
 	: "%r" (__m0), \
 	"r" (__m1)); \
 	(pl) = __m0 * __m1; \
diff -druNp --no-dereference linux-libre-4.4.222-gnu/Makefile linux-libre-4.4.223-gnu/Makefile
--- linux-libre-4.4.222-gnu/Makefile	2020-05-05 15:12:56.000000000 -0400
+++ linux-libre-4.4.223-gnu/Makefile	2020-05-10 18:47:55.000000000 -0400
@@ -1,6 +1,6 @@
 VERSION = 4
 PATCHLEVEL = 4
-SUBLEVEL = 222
+SUBLEVEL = 223
 EXTRAVERSION = -gnu
 NAME = Blurry Fish Butt
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/batman-adv/main.c linux-libre-4.4.223-gnu/net/batman-adv/main.c
--- linux-libre-4.4.222-gnu/net/batman-adv/main.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/batman-adv/main.c	2020-05-10 04:26:37.000000000 -0400
@@ -747,7 +747,7 @@ static u16 batadv_tvlv_container_list_si
 static void batadv_tvlv_container_remove(struct batadv_priv *bat_priv,
 					 struct batadv_tvlv_container *tvlv)
 {
-	lockdep_assert_held(&bat_priv->tvlv.handler_list_lock);
+	lockdep_assert_held(&bat_priv->tvlv.container_list_lock);
 
 	if (!tvlv)
 		return;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/batman-adv/translation-table.c linux-libre-4.4.223-gnu/net/batman-adv/translation-table.c
--- linux-libre-4.4.222-gnu/net/batman-adv/translation-table.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/batman-adv/translation-table.c	2020-05-10 04:26:37.000000000 -0400
@@ -614,8 +614,10 @@ bool batadv_tt_local_add(struct net_devi
 
 	/* increase the refcounter of the related vlan */
 	vlan = batadv_softif_vlan_get(bat_priv, vid);
-	if (WARN(!vlan, "adding TT local entry %pM to non-existent VLAN %d",
-		 addr, BATADV_PRINT_VID(vid))) {
+	if (!vlan) {
+		net_ratelimited_function(batadv_info, soft_iface,
+					 "adding TT local entry %pM to non-existent VLAN %d\n",
+					 addr, BATADV_PRINT_VID(vid));
 		kfree(tt_local);
 		tt_local = NULL;
 		goto out;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/bridge/br_fdb.c linux-libre-4.4.223-gnu/net/bridge/br_fdb.c
--- linux-libre-4.4.222-gnu/net/bridge/br_fdb.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/bridge/br_fdb.c	2020-05-10 04:26:37.000000000 -0400
@@ -266,7 +266,7 @@ void br_fdb_change_mac_address(struct ne
 
 	/* If old entry was unassociated with any port, then delete it. */
 	f = __br_fdb_get(br, br->dev->dev_addr, 0);
-	if (f && f->is_local && !f->dst)
+	if (f && f->is_local && !f->dst && !f->added_by_user)
 		fdb_delete_local(br, NULL, f);
 
 	fdb_insert(br, NULL, newaddr, 0);
@@ -281,7 +281,7 @@ void br_fdb_change_mac_address(struct ne
 		if (!br_vlan_should_use(v))
 			continue;
 		f = __br_fdb_get(br, br->dev->dev_addr, v->vid);
-		if (f && f->is_local && !f->dst)
+		if (f && f->is_local && !f->dst && !f->added_by_user)
 			fdb_delete_local(br, NULL, f);
 		fdb_insert(br, NULL, newaddr, v->vid);
 	}
@@ -758,20 +758,25 @@ out:
 }
 
 /* Update (create or replace) forwarding database entry */
-static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr,
-			 __u16 state, __u16 flags, __u16 vid)
+static int fdb_add_entry(struct net_bridge *br, struct net_bridge_port *source,
+			 const __u8 *addr, __u16 state, __u16 flags, __u16 vid)
 {
-	struct net_bridge *br = source->br;
 	struct hlist_head *head = &br->hash[br_mac_hash(addr, vid)];
 	struct net_bridge_fdb_entry *fdb;
 	bool modified = false;
 
 	/* If the port cannot learn allow only local and static entries */
-	if (!(state & NUD_PERMANENT) && !(state & NUD_NOARP) &&
+	if (source && !(state & NUD_PERMANENT) && !(state & NUD_NOARP) &&
 	    !(source->state == BR_STATE_LEARNING ||
 	      source->state == BR_STATE_FORWARDING))
 		return -EPERM;
 
+	if (!source && !(state & NUD_PERMANENT)) {
+		pr_info("bridge: RTM_NEWNEIGH %s without NUD_PERMANENT\n",
+			br->dev->name);
+		return -EINVAL;
+	}
+
 	fdb = fdb_find(head, addr, vid);
 	if (fdb == NULL) {
 		if (!(flags & NLM_F_CREATE))
@@ -826,22 +831,28 @@ static int fdb_add_entry(struct net_brid
 	return 0;
 }
 
-static int __br_fdb_add(struct ndmsg *ndm, struct net_bridge_port *p,
-	       const unsigned char *addr, u16 nlh_flags, u16 vid)
+static int __br_fdb_add(struct ndmsg *ndm, struct net_bridge *br,
+			struct net_bridge_port *p, const unsigned char *addr,
+			u16 nlh_flags, u16 vid)
 {
 	int err = 0;
 
 	if (ndm->ndm_flags & NTF_USE) {
+		if (!p) {
+			pr_info("bridge: RTM_NEWNEIGH %s with NTF_USE is not supported\n",
+				br->dev->name);
+			return -EINVAL;
+		}
 		local_bh_disable();
 		rcu_read_lock();
-		br_fdb_update(p->br, p, addr, vid, true);
+		br_fdb_update(br, p, addr, vid, true);
 		rcu_read_unlock();
 		local_bh_enable();
 	} else {
-		spin_lock_bh(&p->br->hash_lock);
-		err = fdb_add_entry(p, addr, ndm->ndm_state,
+		spin_lock_bh(&br->hash_lock);
+		err = fdb_add_entry(br, p, addr, ndm->ndm_state,
 				    nlh_flags, vid);
-		spin_unlock_bh(&p->br->hash_lock);
+		spin_unlock_bh(&br->hash_lock);
 	}
 
 	return err;
@@ -878,6 +889,7 @@ int br_fdb_add(struct ndmsg *ndm, struct
 				dev->name);
 			return -EINVAL;
 		}
+		br = p->br;
 		vg = nbp_vlan_group(p);
 	}
 
@@ -889,15 +901,9 @@ int br_fdb_add(struct ndmsg *ndm, struct
 		}
 
 		/* VID was specified, so use it. */
-		if (dev->priv_flags & IFF_EBRIDGE)
-			err = br_fdb_insert(br, NULL, addr, vid);
-		else
-			err = __br_fdb_add(ndm, p, addr, nlh_flags, vid);
+		err = __br_fdb_add(ndm, br, p, addr, nlh_flags, vid);
 	} else {
-		if (dev->priv_flags & IFF_EBRIDGE)
-			err = br_fdb_insert(br, NULL, addr, 0);
-		else
-			err = __br_fdb_add(ndm, p, addr, nlh_flags, 0);
+		err = __br_fdb_add(ndm, br, p, addr, nlh_flags, 0);
 		if (err || !vg || !vg->num_vlans)
 			goto out;
 
@@ -908,11 +914,7 @@ int br_fdb_add(struct ndmsg *ndm, struct
 		list_for_each_entry(v, &vg->vlan_list, vlist) {
 			if (!br_vlan_should_use(v))
 				continue;
-			if (dev->priv_flags & IFF_EBRIDGE)
-				err = br_fdb_insert(br, NULL, addr, v->vid);
-			else
-				err = __br_fdb_add(ndm, p, addr, nlh_flags,
-						   v->vid);
+			err = __br_fdb_add(ndm, br, p, addr, nlh_flags, v->vid);
 			if (err)
 				goto out;
 		}
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/bridge/br_input.c linux-libre-4.4.223-gnu/net/bridge/br_input.c
--- linux-libre-4.4.222-gnu/net/bridge/br_input.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/bridge/br_input.c	2020-05-10 04:26:37.000000000 -0400
@@ -78,13 +78,10 @@ static void br_do_proxy_arp(struct sk_bu
 
 	BR_INPUT_SKB_CB(skb)->proxyarp_replied = false;
 
-	if (dev->flags & IFF_NOARP)
+	if ((dev->flags & IFF_NOARP) ||
+	    !pskb_may_pull(skb, arp_hdr_len(dev)))
 		return;
 
-	if (!pskb_may_pull(skb, arp_hdr_len(dev))) {
-		dev->stats.tx_dropped++;
-		return;
-	}
 	parp = arp_hdr(skb);
 
 	if (parp->ar_pro != htons(ETH_P_IP) ||
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/core/dev.c linux-libre-4.4.223-gnu/net/core/dev.c
--- linux-libre-4.4.222-gnu/net/core/dev.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/core/dev.c	2020-05-10 04:26:37.000000000 -0400
@@ -4320,6 +4320,7 @@ static enum gro_result dev_gro_receive(s
 		NAPI_GRO_CB(skb)->free = 0;
 		NAPI_GRO_CB(skb)->encap_mark = 0;
 		NAPI_GRO_CB(skb)->recursion_counter = 0;
+		NAPI_GRO_CB(skb)->is_fou = 0;
 		NAPI_GRO_CB(skb)->gro_remcsum_start = 0;
 
 		/* Setup for GRO checksum validation */
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/core/flow_dissector.c linux-libre-4.4.223-gnu/net/core/flow_dissector.c
--- linux-libre-4.4.222-gnu/net/core/flow_dissector.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/core/flow_dissector.c	2020-05-10 04:26:37.000000000 -0400
@@ -178,15 +178,16 @@ ip:
 
 		ip_proto = iph->protocol;
 
-		if (!dissector_uses_key(flow_dissector,
-					FLOW_DISSECTOR_KEY_IPV4_ADDRS))
-			break;
+		if (dissector_uses_key(flow_dissector,
+				       FLOW_DISSECTOR_KEY_IPV4_ADDRS)) {
+			key_addrs = skb_flow_dissector_target(flow_dissector,
+							      FLOW_DISSECTOR_KEY_IPV4_ADDRS,
+							      target_container);
 
-		key_addrs = skb_flow_dissector_target(flow_dissector,
-			      FLOW_DISSECTOR_KEY_IPV4_ADDRS, target_container);
-		memcpy(&key_addrs->v4addrs, &iph->saddr,
-		       sizeof(key_addrs->v4addrs));
-		key_control->addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
+			memcpy(&key_addrs->v4addrs, &iph->saddr,
+			       sizeof(key_addrs->v4addrs));
+			key_control->addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
+		}
 
 		if (ip_is_fragment(iph)) {
 			key_control->flags |= FLOW_DIS_IS_FRAGMENT;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/core/rtnetlink.c linux-libre-4.4.223-gnu/net/core/rtnetlink.c
--- linux-libre-4.4.222-gnu/net/core/rtnetlink.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/core/rtnetlink.c	2020-05-10 04:26:37.000000000 -0400
@@ -253,6 +253,7 @@ int rtnl_unregister(int protocol, int ms
 
 	rtnl_msg_handlers[protocol][msgindex].doit = NULL;
 	rtnl_msg_handlers[protocol][msgindex].dumpit = NULL;
+	rtnl_msg_handlers[protocol][msgindex].calcit = NULL;
 
 	return 0;
 }
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/core/skbuff.c linux-libre-4.4.223-gnu/net/core/skbuff.c
--- linux-libre-4.4.222-gnu/net/core/skbuff.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/core/skbuff.c	2020-05-10 04:26:37.000000000 -0400
@@ -4451,9 +4451,8 @@ int skb_vlan_pop(struct sk_buff *skb)
 	if (likely(skb_vlan_tag_present(skb))) {
 		skb->vlan_tci = 0;
 	} else {
-		if (unlikely((skb->protocol != htons(ETH_P_8021Q) &&
-			      skb->protocol != htons(ETH_P_8021AD)) ||
-			     skb->len < VLAN_ETH_HLEN))
+		if (unlikely(skb->protocol != htons(ETH_P_8021Q) &&
+			     skb->protocol != htons(ETH_P_8021AD)))
 			return 0;
 
 		err = __skb_vlan_pop(skb, &vlan_tci);
@@ -4461,9 +4460,8 @@ int skb_vlan_pop(struct sk_buff *skb)
 			return err;
 	}
 	/* move next vlan tag to hw accel tag */
-	if (likely((skb->protocol != htons(ETH_P_8021Q) &&
-		    skb->protocol != htons(ETH_P_8021AD)) ||
-		   skb->len < VLAN_ETH_HLEN))
+	if (likely(skb->protocol != htons(ETH_P_8021Q) &&
+		   skb->protocol != htons(ETH_P_8021AD)))
 		return 0;
 
 	vlan_proto = skb->protocol;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/core/sock.c linux-libre-4.4.223-gnu/net/core/sock.c
--- linux-libre-4.4.222-gnu/net/core/sock.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/core/sock.c	2020-05-10 04:26:37.000000000 -0400
@@ -484,11 +484,12 @@ int sock_queue_rcv_skb(struct sock *sk,
 }
 EXPORT_SYMBOL(sock_queue_rcv_skb);
 
-int sk_receive_skb(struct sock *sk, struct sk_buff *skb, const int nested)
+int __sk_receive_skb(struct sock *sk, struct sk_buff *skb,
+		     const int nested, unsigned int trim_cap)
 {
 	int rc = NET_RX_SUCCESS;
 
-	if (sk_filter(sk, skb))
+	if (sk_filter_trim_cap(sk, skb, trim_cap))
 		goto discard_and_relse;
 
 	skb->dev = NULL;
@@ -524,7 +525,7 @@ discard_and_relse:
 	kfree_skb(skb);
 	goto out;
 }
-EXPORT_SYMBOL(sk_receive_skb);
+EXPORT_SYMBOL(__sk_receive_skb);
 
 struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie)
 {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/dccp/ipv4.c linux-libre-4.4.223-gnu/net/dccp/ipv4.c
--- linux-libre-4.4.222-gnu/net/dccp/ipv4.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/dccp/ipv4.c	2020-05-10 04:26:37.000000000 -0400
@@ -868,7 +868,7 @@ lookup:
 		goto discard_and_relse;
 	nf_reset(skb);
 
-	return sk_receive_skb(sk, skb, 1);
+	return __sk_receive_skb(sk, skb, 1, dh->dccph_doff * 4);
 
 no_dccp_socket:
 	if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/dccp/ipv6.c linux-libre-4.4.223-gnu/net/dccp/ipv6.c
--- linux-libre-4.4.222-gnu/net/dccp/ipv6.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/dccp/ipv6.c	2020-05-10 04:26:37.000000000 -0400
@@ -741,7 +741,7 @@ lookup:
 	if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
 		goto discard_and_relse;
 
-	return sk_receive_skb(sk, skb, 1) ? -1 : 0;
+	return __sk_receive_skb(sk, skb, 1, dh->dccph_doff * 4) ? -1 : 0;
 
 no_dccp_socket:
 	if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/dsa/slave.c linux-libre-4.4.223-gnu/net/dsa/slave.c
--- linux-libre-4.4.222-gnu/net/dsa/slave.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/dsa/slave.c	2020-05-10 04:26:37.000000000 -0400
@@ -1031,7 +1031,7 @@ static int dsa_slave_phy_setup(struct ds
 	p->phy_interface = mode;
 
 	phy_dn = of_parse_phandle(port_dn, "phy-handle", 0);
-	if (of_phy_is_fixed_link(port_dn)) {
+	if (!phy_dn && of_phy_is_fixed_link(port_dn)) {
 		/* In the case of a fixed PHY, the DT node associated
 		 * to the fixed PHY is the Port DT node
 		 */
@@ -1041,7 +1041,7 @@ static int dsa_slave_phy_setup(struct ds
 			return ret;
 		}
 		phy_is_fixed = true;
-		phy_dn = port_dn;
+		phy_dn = of_node_get(port_dn);
 	}
 
 	if (ds->drv->get_phy_flags)
@@ -1060,6 +1060,7 @@ static int dsa_slave_phy_setup(struct ds
 			ret = dsa_slave_phy_connect(p, slave_dev, phy_id);
 			if (ret) {
 				netdev_err(slave_dev, "failed to connect to phy%d: %d\n", phy_id, ret);
+				of_node_put(phy_dn);
 				return ret;
 			}
 		} else {
@@ -1068,6 +1069,8 @@ static int dsa_slave_phy_setup(struct ds
 						phy_flags,
 						p->phy_interface);
 		}
+
+		of_node_put(phy_dn);
 	}
 
 	if (p->phy && phy_is_fixed)
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/ipv4/devinet.c linux-libre-4.4.223-gnu/net/ipv4/devinet.c
--- linux-libre-4.4.222-gnu/net/ipv4/devinet.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/ipv4/devinet.c	2020-05-10 04:26:37.000000000 -0400
@@ -1814,7 +1814,7 @@ void inet_netconf_notify_devconf(struct
 	struct sk_buff *skb;
 	int err = -ENOBUFS;
 
-	skb = nlmsg_new(inet_netconf_msgsize_devconf(type), GFP_ATOMIC);
+	skb = nlmsg_new(inet_netconf_msgsize_devconf(type), GFP_KERNEL);
 	if (!skb)
 		goto errout;
 
@@ -1826,7 +1826,7 @@ void inet_netconf_notify_devconf(struct
 		kfree_skb(skb);
 		goto errout;
 	}
-	rtnl_notify(skb, net, 0, RTNLGRP_IPV4_NETCONF, NULL, GFP_ATOMIC);
+	rtnl_notify(skb, net, 0, RTNLGRP_IPV4_NETCONF, NULL, GFP_KERNEL);
 	return;
 errout:
 	if (err < 0)
@@ -1883,7 +1883,7 @@ static int inet_netconf_get_devconf(stru
 	}
 
 	err = -ENOBUFS;
-	skb = nlmsg_new(inet_netconf_msgsize_devconf(-1), GFP_ATOMIC);
+	skb = nlmsg_new(inet_netconf_msgsize_devconf(-1), GFP_KERNEL);
 	if (!skb)
 		goto errout;
 
@@ -2007,16 +2007,16 @@ static void inet_forward_change(struct n
 
 	for_each_netdev(net, dev) {
 		struct in_device *in_dev;
+
 		if (on)
 			dev_disable_lro(dev);
-		rcu_read_lock();
-		in_dev = __in_dev_get_rcu(dev);
+
+		in_dev = __in_dev_get_rtnl(dev);
 		if (in_dev) {
 			IN_DEV_CONF_SET(in_dev, FORWARDING, on);
 			inet_netconf_notify_devconf(net, NETCONFA_FORWARDING,
 						    dev->ifindex, &in_dev->cnf);
 		}
-		rcu_read_unlock();
 	}
 }
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/ipv4/fib_frontend.c linux-libre-4.4.223-gnu/net/ipv4/fib_frontend.c
--- linux-libre-4.4.222-gnu/net/ipv4/fib_frontend.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/ipv4/fib_frontend.c	2020-05-10 04:26:37.000000000 -0400
@@ -509,6 +509,7 @@ static int rtentry_to_fib_config(struct
 		if (!dev)
 			return -ENODEV;
 		cfg->fc_oif = dev->ifindex;
+		cfg->fc_table = l3mdev_fib_table(dev);
 		if (colon) {
 			struct in_ifaddr *ifa;
 			struct in_device *in_dev = __in_dev_get_rtnl(dev);
@@ -1034,7 +1035,7 @@ no_promotions:
 			 * First of all, we scan fib_info list searching
 			 * for stray nexthop entries, then ignite fib_flush.
 			 */
-			if (fib_sync_down_addr(dev_net(dev), ifa->ifa_local))
+			if (fib_sync_down_addr(dev, ifa->ifa_local))
 				fib_flush(dev_net(dev));
 		}
 	}
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/ipv4/fib_semantics.c linux-libre-4.4.223-gnu/net/ipv4/fib_semantics.c
--- linux-libre-4.4.222-gnu/net/ipv4/fib_semantics.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/ipv4/fib_semantics.c	2020-05-10 04:26:37.000000000 -0400
@@ -1069,6 +1069,7 @@ struct fib_info *fib_create_info(struct
 	fi->fib_priority = cfg->fc_priority;
 	fi->fib_prefsrc = cfg->fc_prefsrc;
 	fi->fib_type = cfg->fc_type;
+	fi->fib_tb_id = cfg->fc_table;
 
 	fi->fib_nhs = nhs;
 	change_nexthops(fi) {
@@ -1352,18 +1353,21 @@ nla_put_failure:
  *   referring to it.
  * - device went down -> we must shutdown all nexthops going via it.
  */
-int fib_sync_down_addr(struct net *net, __be32 local)
+int fib_sync_down_addr(struct net_device *dev, __be32 local)
 {
 	int ret = 0;
 	unsigned int hash = fib_laddr_hashfn(local);
 	struct hlist_head *head = &fib_info_laddrhash[hash];
+	int tb_id = l3mdev_fib_table(dev) ? : RT_TABLE_MAIN;
+	struct net *net = dev_net(dev);
 	struct fib_info *fi;
 
 	if (!fib_info_laddrhash || local == 0)
 		return 0;
 
 	hlist_for_each_entry(fi, head, fib_lhash) {
-		if (!net_eq(fi->fib_net, net))
+		if (!net_eq(fi->fib_net, net) ||
+		    fi->fib_tb_id != tb_id)
 			continue;
 		if (fi->fib_prefsrc == local) {
 			fi->fib_flags |= RTNH_F_DEAD;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/ipv4/fib_trie.c linux-libre-4.4.223-gnu/net/ipv4/fib_trie.c
--- linux-libre-4.4.222-gnu/net/ipv4/fib_trie.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/ipv4/fib_trie.c	2020-05-10 04:26:37.000000000 -0400
@@ -1714,8 +1714,10 @@ struct fib_table *fib_trie_unmerge(struc
 				local_l = fib_find_node(lt, &local_tp, l->key);
 
 			if (fib_insert_alias(lt, local_tp, local_l, new_fa,
-					     NULL, l->key))
+					     NULL, l->key)) {
+				kmem_cache_free(fn_alias_kmem, new_fa);
 				goto out;
+			}
 		}
 
 		/* stop loop if key wrapped back to 0 */
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/ipv4/fou.c linux-libre-4.4.223-gnu/net/ipv4/fou.c
--- linux-libre-4.4.222-gnu/net/ipv4/fou.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/ipv4/fou.c	2020-05-10 04:26:37.000000000 -0400
@@ -205,6 +205,9 @@ static struct sk_buff **fou_gro_receive(
 	 */
 	NAPI_GRO_CB(skb)->encap_mark = 0;
 
+	/* Flag this frame as already having an outer encap header */
+	NAPI_GRO_CB(skb)->is_fou = 1;
+
 	rcu_read_lock();
 	offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads;
 	ops = rcu_dereference(offloads[proto]);
@@ -372,6 +375,9 @@ static struct sk_buff **gue_gro_receive(
 	 */
 	NAPI_GRO_CB(skb)->encap_mark = 0;
 
+	/* Flag this frame as already having an outer encap header */
+	NAPI_GRO_CB(skb)->is_fou = 1;
+
 	rcu_read_lock();
 	offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads;
 	ops = rcu_dereference(offloads[guehdr->proto_ctype]);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/ipv4/gre_offload.c linux-libre-4.4.223-gnu/net/ipv4/gre_offload.c
--- linux-libre-4.4.222-gnu/net/ipv4/gre_offload.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/ipv4/gre_offload.c	2020-05-10 04:26:37.000000000 -0400
@@ -151,6 +151,14 @@ static struct sk_buff **gre_gro_receive(
 	if ((greh->flags & ~(GRE_KEY|GRE_CSUM)) != 0)
 		goto out;
 
+	/* We can only support GRE_CSUM if we can track the location of
+	 * the GRE header.  In the case of FOU/GUE we cannot because the
+	 * outer UDP header displaces the GRE header leaving us in a state
+	 * of limbo.
+	 */
+	if ((greh->flags & GRE_CSUM) && NAPI_GRO_CB(skb)->is_fou)
+		goto out;
+
 	type = greh->protocol;
 
 	rcu_read_lock();
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/ipv4/icmp.c linux-libre-4.4.223-gnu/net/ipv4/icmp.c
--- linux-libre-4.4.222-gnu/net/ipv4/icmp.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/ipv4/icmp.c	2020-05-10 04:26:37.000000000 -0400
@@ -478,7 +478,7 @@ static struct rtable *icmp_route_lookup(
 	fl4->flowi4_proto = IPPROTO_ICMP;
 	fl4->fl4_icmp_type = type;
 	fl4->fl4_icmp_code = code;
-	fl4->flowi4_oif = l3mdev_master_ifindex(skb_in->dev);
+	fl4->flowi4_oif = l3mdev_master_ifindex(skb_dst(skb_in)->dev);
 
 	security_skb_classify_flow(skb_in, flowi4_to_flowi(fl4));
 	rt = __ip_route_output_key_hash(net, fl4,
@@ -503,7 +503,7 @@ static struct rtable *icmp_route_lookup(
 	if (err)
 		goto relookup_failed;
 
-	if (inet_addr_type_dev_table(net, skb_in->dev,
+	if (inet_addr_type_dev_table(net, skb_dst(skb_in)->dev,
 				     fl4_dec.saddr) == RTN_LOCAL) {
 		rt2 = __ip_route_output_key(net, &fl4_dec);
 		if (IS_ERR(rt2))
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/ipv4/ip_gre.c linux-libre-4.4.223-gnu/net/ipv4/ip_gre.c
--- linux-libre-4.4.222-gnu/net/ipv4/ip_gre.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/ipv4/ip_gre.c	2020-05-10 04:26:37.000000000 -0400
@@ -520,7 +520,8 @@ static struct rtable *gre_get_rt(struct
 	return ip_route_output_key(net, fl);
 }
 
-static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev)
+static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev,
+			__be16 proto)
 {
 	struct ip_tunnel_info *tun_info;
 	const struct ip_tunnel_key *key;
@@ -563,7 +564,7 @@ static void gre_fb_xmit(struct sk_buff *
 	}
 
 	flags = tun_info->key.tun_flags & (TUNNEL_CSUM | TUNNEL_KEY);
-	build_header(skb, tunnel_hlen, flags, htons(ETH_P_TEB),
+	build_header(skb, tunnel_hlen, flags, proto,
 		     tunnel_id_to_key(tun_info->key.tun_id), 0);
 
 	df = key->tun_flags & TUNNEL_DONT_FRAGMENT ?  htons(IP_DF) : 0;
@@ -605,7 +606,7 @@ static netdev_tx_t ipgre_xmit(struct sk_
 	const struct iphdr *tnl_params;
 
 	if (tunnel->collect_md) {
-		gre_fb_xmit(skb, dev);
+		gre_fb_xmit(skb, dev, skb->protocol);
 		return NETDEV_TX_OK;
 	}
 
@@ -649,7 +650,7 @@ static netdev_tx_t gre_tap_xmit(struct s
 	struct ip_tunnel *tunnel = netdev_priv(dev);
 
 	if (tunnel->collect_md) {
-		gre_fb_xmit(skb, dev);
+		gre_fb_xmit(skb, dev, htons(ETH_P_TEB));
 		return NETDEV_TX_OK;
 	}
 
@@ -851,9 +852,16 @@ static void __gre_tunnel_init(struct net
 	dev->hw_features	|= GRE_FEATURES;
 
 	if (!(tunnel->parms.o_flags & TUNNEL_SEQ)) {
-		/* TCP offload with GRE SEQ is not supported. */
-		dev->features    |= NETIF_F_GSO_SOFTWARE;
-		dev->hw_features |= NETIF_F_GSO_SOFTWARE;
+		/* TCP offload with GRE SEQ is not supported, nor
+		 * can we support 2 levels of outer headers requiring
+		 * an update.
+		 */
+		if (!(tunnel->parms.o_flags & TUNNEL_CSUM) ||
+		    (tunnel->encap.type == TUNNEL_ENCAP_NONE)) {
+			dev->features    |= NETIF_F_GSO_SOFTWARE;
+			dev->hw_features |= NETIF_F_GSO_SOFTWARE;
+		}
+
 		/* Can use a lockless transmit, unless we generate
 		 * output sequences
 		 */
@@ -875,7 +883,7 @@ static int ipgre_tunnel_init(struct net_
 	netif_keep_dst(dev);
 	dev->addr_len		= 4;
 
-	if (iph->daddr) {
+	if (iph->daddr && !tunnel->collect_md) {
 #ifdef CONFIG_NET_IPGRE_BROADCAST
 		if (ipv4_is_multicast(iph->daddr)) {
 			if (!iph->saddr)
@@ -884,8 +892,9 @@ static int ipgre_tunnel_init(struct net_
 			dev->header_ops = &ipgre_header_ops;
 		}
 #endif
-	} else
+	} else if (!tunnel->collect_md) {
 		dev->header_ops = &ipgre_header_ops;
+	}
 
 	return ip_tunnel_init(dev);
 }
@@ -928,6 +937,11 @@ static int ipgre_tunnel_validate(struct
 	if (flags & (GRE_VERSION|GRE_ROUTING))
 		return -EINVAL;
 
+	if (data[IFLA_GRE_COLLECT_METADATA] &&
+	    data[IFLA_GRE_ENCAP_TYPE] &&
+	    nla_get_u16(data[IFLA_GRE_ENCAP_TYPE]) != TUNNEL_ENCAP_NONE)
+		return -EINVAL;
+
 	return 0;
 }
 
@@ -1230,6 +1244,7 @@ struct net_device *gretap_fb_dev_create(
 {
 	struct nlattr *tb[IFLA_MAX + 1];
 	struct net_device *dev;
+	LIST_HEAD(list_kill);
 	struct ip_tunnel *t;
 	int err;
 
@@ -1245,8 +1260,10 @@ struct net_device *gretap_fb_dev_create(
 	t->collect_md = true;
 
 	err = ipgre_newlink(net, dev, tb, NULL);
-	if (err < 0)
-		goto out;
+	if (err < 0) {
+		free_netdev(dev);
+		return ERR_PTR(err);
+	}
 
 	/* openvswitch users expect packet sizes to be unrestricted,
 	 * so set the largest MTU we can.
@@ -1255,9 +1272,14 @@ struct net_device *gretap_fb_dev_create(
 	if (err)
 		goto out;
 
+	err = rtnl_configure_link(dev, NULL);
+	if (err < 0)
+		goto out;
+
 	return dev;
 out:
-	free_netdev(dev);
+	ip_tunnel_dellink(dev, &list_kill);
+	unregister_netdevice_many(&list_kill);
 	return ERR_PTR(err);
 }
 EXPORT_SYMBOL_GPL(gretap_fb_dev_create);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/ipv4/ip_sockglue.c linux-libre-4.4.223-gnu/net/ipv4/ip_sockglue.c
--- linux-libre-4.4.222-gnu/net/ipv4/ip_sockglue.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/ipv4/ip_sockglue.c	2020-05-10 04:26:37.000000000 -0400
@@ -279,9 +279,12 @@ int ip_cmsg_send(struct net *net, struct
 			ipc->ttl = val;
 			break;
 		case IP_TOS:
-			if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)))
+			if (cmsg->cmsg_len == CMSG_LEN(sizeof(int)))
+				val = *(int *)CMSG_DATA(cmsg);
+			else if (cmsg->cmsg_len == CMSG_LEN(sizeof(u8)))
+				val = *(u8 *)CMSG_DATA(cmsg);
+			else
 				return -EINVAL;
-			val = *(int *)CMSG_DATA(cmsg);
 			if (val < 0 || val > 255)
 				return -EINVAL;
 			ipc->tos = val;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/ipv4/netfilter/nft_dup_ipv4.c linux-libre-4.4.223-gnu/net/ipv4/netfilter/nft_dup_ipv4.c
--- linux-libre-4.4.222-gnu/net/ipv4/netfilter/nft_dup_ipv4.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/ipv4/netfilter/nft_dup_ipv4.c	2020-05-10 04:26:37.000000000 -0400
@@ -28,7 +28,7 @@ static void nft_dup_ipv4_eval(const stru
 	struct in_addr gw = {
 		.s_addr = (__force __be32)regs->data[priv->sreg_addr],
 	};
-	int oif = regs->data[priv->sreg_dev];
+	int oif = priv->sreg_dev ? regs->data[priv->sreg_dev] : -1;
 
 	nf_dup_ipv4(pkt->net, pkt->skb, pkt->hook, &gw, oif);
 }
@@ -59,7 +59,9 @@ static int nft_dup_ipv4_dump(struct sk_b
 {
 	struct nft_dup_ipv4 *priv = nft_expr_priv(expr);
 
-	if (nft_dump_register(skb, NFTA_DUP_SREG_ADDR, priv->sreg_addr) ||
+	if (nft_dump_register(skb, NFTA_DUP_SREG_ADDR, priv->sreg_addr))
+		goto nla_put_failure;
+	if (priv->sreg_dev &&
 	    nft_dump_register(skb, NFTA_DUP_SREG_DEV, priv->sreg_dev))
 		goto nla_put_failure;
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/ipv4/route.c linux-libre-4.4.223-gnu/net/ipv4/route.c
--- linux-libre-4.4.222-gnu/net/ipv4/route.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/ipv4/route.c	2020-05-10 04:26:37.000000000 -0400
@@ -477,12 +477,18 @@ u32 ip_idents_reserve(u32 hash, int segs
 	atomic_t *p_id = ip_idents + hash % IP_IDENTS_SZ;
 	u32 old = ACCESS_ONCE(*p_tstamp);
 	u32 now = (u32)jiffies;
-	u32 delta = 0;
+	u32 new, delta = 0;
 
 	if (old != now && cmpxchg(p_tstamp, old, now) == old)
 		delta = prandom_u32_max(now - old);
 
-	return atomic_add_return(segs + delta, p_id) - segs;
+	/* Do not use atomic_add_return() as it makes UBSAN unhappy */
+	do {
+		old = (u32)atomic_read(p_id);
+		new = old + delta + segs;
+	} while (atomic_cmpxchg(p_id, old, new) != old);
+
+	return new - segs;
 }
 EXPORT_SYMBOL(ip_idents_reserve);
 
@@ -1494,9 +1500,9 @@ static void rt_set_nexthop(struct rtable
 #endif
 }
 
-static struct rtable *rt_dst_alloc(struct net_device *dev,
-				   unsigned int flags, u16 type,
-				   bool nopolicy, bool noxfrm, bool will_cache)
+struct rtable *rt_dst_alloc(struct net_device *dev,
+			    unsigned int flags, u16 type,
+			    bool nopolicy, bool noxfrm, bool will_cache)
 {
 	struct rtable *rt;
 
@@ -1525,6 +1531,7 @@ static struct rtable *rt_dst_alloc(struc
 
 	return rt;
 }
+EXPORT_SYMBOL(rt_dst_alloc);
 
 /* called in rcu_read_lock() section */
 static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/ipv4/tcp_input.c linux-libre-4.4.223-gnu/net/ipv4/tcp_input.c
--- linux-libre-4.4.222-gnu/net/ipv4/tcp_input.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/ipv4/tcp_input.c	2020-05-10 04:26:37.000000000 -0400
@@ -2926,7 +2926,10 @@ static void tcp_update_rtt_min(struct so
 {
 	const u32 now = tcp_time_stamp, wlen = sysctl_tcp_min_rtt_wlen * HZ;
 	struct rtt_meas *m = tcp_sk(sk)->rtt_min;
-	struct rtt_meas rttm = { .rtt = (rtt_us ? : 1), .ts = now };
+	struct rtt_meas rttm = {
+		.rtt = likely(rtt_us) ? rtt_us : jiffies_to_usecs(1),
+		.ts = now,
+	};
 	u32 elapsed;
 
 	/* Check if the new measurement updates the 1st, 2nd, or 3rd choices */
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/ipv4/udp.c linux-libre-4.4.223-gnu/net/ipv4/udp.c
--- linux-libre-4.4.222-gnu/net/ipv4/udp.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/ipv4/udp.c	2020-05-10 04:26:37.000000000 -0400
@@ -1685,10 +1685,10 @@ static int __udp4_lib_mcast_deliver(stru
 
 	if (use_hash2) {
 		hash2_any = udp4_portaddr_hash(net, htonl(INADDR_ANY), hnum) &
-			    udp_table.mask;
-		hash2 = udp4_portaddr_hash(net, daddr, hnum) & udp_table.mask;
+			    udptable->mask;
+		hash2 = udp4_portaddr_hash(net, daddr, hnum) & udptable->mask;
 start_lookup:
-		hslot = &udp_table.hash2[hash2];
+		hslot = &udptable->hash2[hash2];
 		offset = offsetof(typeof(*sk), __sk_common.skc_portaddr_node);
 	}
 
@@ -1754,8 +1754,11 @@ static inline int udp4_csum_init(struct
 		}
 	}
 
-	return skb_checksum_init_zero_check(skb, proto, uh->check,
-					    inet_compute_pseudo);
+	/* Note, we are only interested in != 0 or == 0, thus the
+	 * force to int.
+	 */
+	return (__force int)skb_checksum_init_zero_check(skb, proto, uh->check,
+							 inet_compute_pseudo);
 }
 
 /*
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/ipv6/addrconf.c linux-libre-4.4.223-gnu/net/ipv6/addrconf.c
--- linux-libre-4.4.222-gnu/net/ipv6/addrconf.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/ipv6/addrconf.c	2020-05-10 04:26:37.000000000 -0400
@@ -540,7 +540,7 @@ void inet6_netconf_notify_devconf(struct
 	struct sk_buff *skb;
 	int err = -ENOBUFS;
 
-	skb = nlmsg_new(inet6_netconf_msgsize_devconf(type), GFP_ATOMIC);
+	skb = nlmsg_new(inet6_netconf_msgsize_devconf(type), GFP_KERNEL);
 	if (!skb)
 		goto errout;
 
@@ -552,7 +552,7 @@ void inet6_netconf_notify_devconf(struct
 		kfree_skb(skb);
 		goto errout;
 	}
-	rtnl_notify(skb, net, 0, RTNLGRP_IPV6_NETCONF, NULL, GFP_ATOMIC);
+	rtnl_notify(skb, net, 0, RTNLGRP_IPV6_NETCONF, NULL, GFP_KERNEL);
 	return;
 errout:
 	rtnl_set_sk_err(net, RTNLGRP_IPV6_NETCONF, err);
@@ -771,7 +771,14 @@ static int addrconf_fixup_forwarding(str
 	}
 
 	if (p == &net->ipv6.devconf_all->forwarding) {
+		int old_dflt = net->ipv6.devconf_dflt->forwarding;
+
 		net->ipv6.devconf_dflt->forwarding = newf;
+		if ((!newf) ^ (!old_dflt))
+			inet6_netconf_notify_devconf(net, NETCONFA_FORWARDING,
+						     NETCONFA_IFINDEX_DEFAULT,
+						     net->ipv6.devconf_dflt);
+
 		addrconf_forward_change(net, newf);
 		if ((!newf) ^ (!old))
 			inet6_netconf_notify_devconf(net, NETCONFA_FORWARDING,
@@ -3146,6 +3153,7 @@ static int addrconf_notify(struct notifi
 			   void *ptr)
 {
 	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+	struct netdev_notifier_changeupper_info *info;
 	struct inet6_dev *idev = __in6_dev_get(dev);
 	struct net *net = dev_net(dev);
 	int run_pending = 0;
@@ -3307,6 +3315,15 @@ static int addrconf_notify(struct notifi
 	case NETDEV_POST_TYPE_CHANGE:
 		addrconf_type_change(dev, event);
 		break;
+
+	case NETDEV_CHANGEUPPER:
+		info = ptr;
+
+		/* flush all routes if dev is linked to or unlinked from
+		 * an L3 master device (e.g., VRF)
+		 */
+		if (info->upper_dev && netif_is_l3_master(info->upper_dev))
+			addrconf_ifdown(dev, 0);
 	}
 
 	return NOTIFY_OK;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/ipv6/icmp.c linux-libre-4.4.223-gnu/net/ipv6/icmp.c
--- linux-libre-4.4.222-gnu/net/ipv6/icmp.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/ipv6/icmp.c	2020-05-10 04:26:37.000000000 -0400
@@ -445,6 +445,8 @@ static void icmp6_send(struct sk_buff *s
 
 	if (__ipv6_addr_needs_scope_id(addr_type))
 		iif = skb->dev->ifindex;
+	else
+		iif = l3mdev_master_ifindex(skb_dst(skb)->dev);
 
 	/*
 	 *	Must not send error if the source does not uniquely
@@ -499,9 +501,6 @@ static void icmp6_send(struct sk_buff *s
 	else if (!fl6.flowi6_oif)
 		fl6.flowi6_oif = np->ucast_oif;
 
-	if (!fl6.flowi6_oif)
-		fl6.flowi6_oif = l3mdev_master_ifindex(skb->dev);
-
 	dst = icmpv6_route_lookup(net, skb, sk, &fl6);
 	if (IS_ERR(dst))
 		goto out;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/ipv6/ip6_checksum.c linux-libre-4.4.223-gnu/net/ipv6/ip6_checksum.c
--- linux-libre-4.4.222-gnu/net/ipv6/ip6_checksum.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/ipv6/ip6_checksum.c	2020-05-10 04:26:37.000000000 -0400
@@ -84,9 +84,12 @@ int udp6_csum_init(struct sk_buff *skb,
 	 * we accept a checksum of zero here. When we find the socket
 	 * for the UDP packet we'll check if that socket allows zero checksum
 	 * for IPv6 (set by socket option).
+	 *
+	 * Note, we are only interested in != 0 or == 0, thus the
+	 * force to int.
 	 */
-	return skb_checksum_init_zero_check(skb, proto, uh->check,
-					   ip6_compute_pseudo);
+	return (__force int)skb_checksum_init_zero_check(skb, proto, uh->check,
+							 ip6_compute_pseudo);
 }
 EXPORT_SYMBOL(udp6_csum_init);
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/ipv6/ip6mr.c linux-libre-4.4.223-gnu/net/ipv6/ip6mr.c
--- linux-libre-4.4.222-gnu/net/ipv6/ip6mr.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/ipv6/ip6mr.c	2020-05-10 04:26:37.000000000 -0400
@@ -1594,14 +1594,15 @@ static int ip6mr_sk_init(struct mr6_tabl
 	if (likely(mrt->mroute6_sk == NULL)) {
 		mrt->mroute6_sk = sk;
 		net->ipv6.devconf_all->mc_forwarding++;
-		inet6_netconf_notify_devconf(net, NETCONFA_MC_FORWARDING,
-					     NETCONFA_IFINDEX_ALL,
-					     net->ipv6.devconf_all);
-	}
-	else
+	} else {
 		err = -EADDRINUSE;
+	}
 	write_unlock_bh(&mrt_lock);
 
+	if (!err)
+		inet6_netconf_notify_devconf(net, NETCONFA_MC_FORWARDING,
+					     NETCONFA_IFINDEX_ALL,
+					     net->ipv6.devconf_all);
 	rtnl_unlock();
 
 	return err;
@@ -1619,11 +1620,11 @@ int ip6mr_sk_done(struct sock *sk)
 			write_lock_bh(&mrt_lock);
 			mrt->mroute6_sk = NULL;
 			net->ipv6.devconf_all->mc_forwarding--;
+			write_unlock_bh(&mrt_lock);
 			inet6_netconf_notify_devconf(net,
 						     NETCONFA_MC_FORWARDING,
 						     NETCONFA_IFINDEX_ALL,
 						     net->ipv6.devconf_all);
-			write_unlock_bh(&mrt_lock);
 
 			mroute_clean_tables(mrt, false);
 			err = 0;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/ipv6/ip6_vti.c linux-libre-4.4.223-gnu/net/ipv6/ip6_vti.c
--- linux-libre-4.4.222-gnu/net/ipv6/ip6_vti.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/ipv6/ip6_vti.c	2020-05-10 04:26:37.000000000 -0400
@@ -324,11 +324,9 @@ static int vti6_rcv(struct sk_buff *skb)
 			goto discard;
 		}
 
-		XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = t;
-
 		rcu_read_unlock();
 
-		return xfrm6_rcv(skb);
+		return xfrm6_rcv_tnl(skb, t);
 	}
 	rcu_read_unlock();
 	return -EINVAL;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/ipv6/netfilter/nft_dup_ipv6.c linux-libre-4.4.223-gnu/net/ipv6/netfilter/nft_dup_ipv6.c
--- linux-libre-4.4.222-gnu/net/ipv6/netfilter/nft_dup_ipv6.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/ipv6/netfilter/nft_dup_ipv6.c	2020-05-10 04:26:37.000000000 -0400
@@ -26,7 +26,7 @@ static void nft_dup_ipv6_eval(const stru
 {
 	struct nft_dup_ipv6 *priv = nft_expr_priv(expr);
 	struct in6_addr *gw = (struct in6_addr *)&regs->data[priv->sreg_addr];
-	int oif = regs->data[priv->sreg_dev];
+	int oif = priv->sreg_dev ? regs->data[priv->sreg_dev] : -1;
 
 	nf_dup_ipv6(pkt->net, pkt->skb, pkt->hook, gw, oif);
 }
@@ -57,7 +57,9 @@ static int nft_dup_ipv6_dump(struct sk_b
 {
 	struct nft_dup_ipv6 *priv = nft_expr_priv(expr);
 
-	if (nft_dump_register(skb, NFTA_DUP_SREG_ADDR, priv->sreg_addr) ||
+	if (nft_dump_register(skb, NFTA_DUP_SREG_ADDR, priv->sreg_addr))
+		goto nla_put_failure;
+	if (priv->sreg_dev &&
 	    nft_dump_register(skb, NFTA_DUP_SREG_DEV, priv->sreg_dev))
 		goto nla_put_failure;
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/ipv6/route.c linux-libre-4.4.223-gnu/net/ipv6/route.c
--- linux-libre-4.4.222-gnu/net/ipv6/route.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/ipv6/route.c	2020-05-10 04:26:37.000000000 -0400
@@ -101,11 +101,13 @@ static int rt6_score_route(struct rt6_in
 #ifdef CONFIG_IPV6_ROUTE_INFO
 static struct rt6_info *rt6_add_route_info(struct net *net,
 					   const struct in6_addr *prefix, int prefixlen,
-					   const struct in6_addr *gwaddr, int ifindex,
+					   const struct in6_addr *gwaddr,
+					   struct net_device *dev,
 					   unsigned int pref);
 static struct rt6_info *rt6_get_route_info(struct net *net,
 					   const struct in6_addr *prefix, int prefixlen,
-					   const struct in6_addr *gwaddr, int ifindex);
+					   const struct in6_addr *gwaddr,
+					   struct net_device *dev);
 #endif
 
 struct uncached_list {
@@ -337,9 +339,9 @@ static struct rt6_info *__ip6_dst_alloc(
 	return rt;
 }
 
-static struct rt6_info *ip6_dst_alloc(struct net *net,
-				      struct net_device *dev,
-				      int flags)
+struct rt6_info *ip6_dst_alloc(struct net *net,
+			       struct net_device *dev,
+			       int flags)
 {
 	struct rt6_info *rt = __ip6_dst_alloc(net, dev, flags);
 
@@ -363,6 +365,7 @@ static struct rt6_info *ip6_dst_alloc(st
 
 	return rt;
 }
+EXPORT_SYMBOL(ip6_dst_alloc);
 
 static void ip6_dst_destroy(struct dst_entry *dst)
 {
@@ -801,7 +804,7 @@ int rt6_route_rcv(struct net_device *dev
 		rt = rt6_get_dflt_router(gwaddr, dev);
 	else
 		rt = rt6_get_route_info(net, prefix, rinfo->prefix_len,
-					gwaddr, dev->ifindex);
+					gwaddr, dev);
 
 	if (rt && !lifetime) {
 		ip6_del_rt(rt);
@@ -809,8 +812,8 @@ int rt6_route_rcv(struct net_device *dev
 	}
 
 	if (!rt && lifetime)
-		rt = rt6_add_route_info(net, prefix, rinfo->prefix_len, gwaddr, dev->ifindex,
-					pref);
+		rt = rt6_add_route_info(net, prefix, rinfo->prefix_len, gwaddr,
+					dev, pref);
 	else if (rt)
 		rt->rt6i_flags = RTF_ROUTEINFO |
 				 (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref);
@@ -2273,13 +2276,16 @@ static void ip6_rt_copy_init(struct rt6_
 #ifdef CONFIG_IPV6_ROUTE_INFO
 static struct rt6_info *rt6_get_route_info(struct net *net,
 					   const struct in6_addr *prefix, int prefixlen,
-					   const struct in6_addr *gwaddr, int ifindex)
+					   const struct in6_addr *gwaddr,
+					   struct net_device *dev)
 {
+	u32 tb_id = l3mdev_fib_table(dev) ? : RT6_TABLE_INFO;
+	int ifindex = dev->ifindex;
 	struct fib6_node *fn;
 	struct rt6_info *rt = NULL;
 	struct fib6_table *table;
 
-	table = fib6_get_table(net, RT6_TABLE_INFO);
+	table = fib6_get_table(net, tb_id);
 	if (!table)
 		return NULL;
 
@@ -2305,12 +2311,13 @@ out:
 
 static struct rt6_info *rt6_add_route_info(struct net *net,
 					   const struct in6_addr *prefix, int prefixlen,
-					   const struct in6_addr *gwaddr, int ifindex,
+					   const struct in6_addr *gwaddr,
+					   struct net_device *dev,
 					   unsigned int pref)
 {
 	struct fib6_config cfg = {
 		.fc_metric	= IP6_RT_PRIO_USER,
-		.fc_ifindex	= ifindex,
+		.fc_ifindex	= dev->ifindex,
 		.fc_dst_len	= prefixlen,
 		.fc_flags	= RTF_GATEWAY | RTF_ADDRCONF | RTF_ROUTEINFO |
 				  RTF_UP | RTF_PREF(pref),
@@ -2319,7 +2326,7 @@ static struct rt6_info *rt6_add_route_in
 		.fc_nlinfo.nl_net = net,
 	};
 
-	cfg.fc_table = l3mdev_fib_table_by_index(net, ifindex) ? : RT6_TABLE_INFO;
+	cfg.fc_table = l3mdev_fib_table(dev) ? : RT6_TABLE_INFO,
 	cfg.fc_dst = *prefix;
 	cfg.fc_gateway = *gwaddr;
 
@@ -2329,16 +2336,17 @@ static struct rt6_info *rt6_add_route_in
 
 	ip6_route_add(&cfg);
 
-	return rt6_get_route_info(net, prefix, prefixlen, gwaddr, ifindex);
+	return rt6_get_route_info(net, prefix, prefixlen, gwaddr, dev);
 }
 #endif
 
 struct rt6_info *rt6_get_dflt_router(const struct in6_addr *addr, struct net_device *dev)
 {
+	u32 tb_id = l3mdev_fib_table(dev) ? : RT6_TABLE_DFLT;
 	struct rt6_info *rt;
 	struct fib6_table *table;
 
-	table = fib6_get_table(dev_net(dev), RT6_TABLE_DFLT);
+	table = fib6_get_table(dev_net(dev), tb_id);
 	if (!table)
 		return NULL;
 
@@ -2372,20 +2380,20 @@ struct rt6_info *rt6_add_dflt_router(con
 
 	cfg.fc_gateway = *gwaddr;
 
-	ip6_route_add(&cfg);
+	if (!ip6_route_add(&cfg)) {
+		struct fib6_table *table;
+
+		table = fib6_get_table(dev_net(dev), cfg.fc_table);
+		if (table)
+			table->flags |= RT6_TABLE_HAS_DFLT_ROUTER;
+	}
 
 	return rt6_get_dflt_router(gwaddr, dev);
 }
 
-void rt6_purge_dflt_routers(struct net *net)
+static void __rt6_purge_dflt_routers(struct fib6_table *table)
 {
 	struct rt6_info *rt;
-	struct fib6_table *table;
-
-	/* NOTE: Keep consistent with rt6_get_dflt_router */
-	table = fib6_get_table(net, RT6_TABLE_DFLT);
-	if (!table)
-		return;
 
 restart:
 	read_lock_bh(&table->tb6_lock);
@@ -2399,6 +2407,27 @@ restart:
 		}
 	}
 	read_unlock_bh(&table->tb6_lock);
+
+	table->flags &= ~RT6_TABLE_HAS_DFLT_ROUTER;
+}
+
+void rt6_purge_dflt_routers(struct net *net)
+{
+	struct fib6_table *table;
+	struct hlist_head *head;
+	unsigned int h;
+
+	rcu_read_lock();
+
+	for (h = 0; h < FIB6_TABLE_HASHSZ; h++) {
+		head = &net->ipv6.fib_table_hash[h];
+		hlist_for_each_entry_rcu(table, head, tb6_hlist) {
+			if (table->flags & RT6_TABLE_HAS_DFLT_ROUTER)
+				__rt6_purge_dflt_routers(table);
+		}
+	}
+
+	rcu_read_unlock();
 }
 
 static void rtmsg_to_fib6_config(struct net *net,
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/ipv6/tcp_ipv6.c linux-libre-4.4.223-gnu/net/ipv6/tcp_ipv6.c
--- linux-libre-4.4.222-gnu/net/ipv6/tcp_ipv6.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/ipv6/tcp_ipv6.c	2020-05-10 04:26:37.000000000 -0400
@@ -815,8 +815,13 @@ static void tcp_v6_send_response(const s
 	fl6.flowi6_proto = IPPROTO_TCP;
 	if (rt6_need_strict(&fl6.daddr) && !oif)
 		fl6.flowi6_oif = tcp_v6_iif(skb);
-	else
+	else {
+		if (!oif && netif_index_is_l3_master(net, skb->skb_iif))
+			oif = skb->skb_iif;
+
 		fl6.flowi6_oif = oif;
+	}
+
 	fl6.flowi6_mark = IP6_REPLY_MARK(net, skb->mark);
 	fl6.fl6_dport = t1->dest;
 	fl6.fl6_sport = t1->source;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/ipv6/udp.c linux-libre-4.4.223-gnu/net/ipv6/udp.c
--- linux-libre-4.4.222-gnu/net/ipv6/udp.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/ipv6/udp.c	2020-05-10 04:26:37.000000000 -0400
@@ -801,10 +801,10 @@ static int __udp6_lib_mcast_deliver(stru
 
 	if (use_hash2) {
 		hash2_any = udp6_portaddr_hash(net, &in6addr_any, hnum) &
-			    udp_table.mask;
-		hash2 = udp6_portaddr_hash(net, daddr, hnum) & udp_table.mask;
+			    udptable->mask;
+		hash2 = udp6_portaddr_hash(net, daddr, hnum) & udptable->mask;
 start_lookup:
-		hslot = &udp_table.hash2[hash2];
+		hslot = &udptable->hash2[hash2];
 		offset = offsetof(typeof(*sk), __sk_common.skc_portaddr_node);
 	}
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/ipv6/xfrm6_input.c linux-libre-4.4.223-gnu/net/ipv6/xfrm6_input.c
--- linux-libre-4.4.222-gnu/net/ipv6/xfrm6_input.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/ipv6/xfrm6_input.c	2020-05-10 04:26:37.000000000 -0400
@@ -21,8 +21,10 @@ int xfrm6_extract_input(struct xfrm_stat
 	return xfrm6_extract_header(skb);
 }
 
-int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
+int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi,
+		  struct ip6_tnl *t)
 {
+	XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6 = t;
 	XFRM_SPI_SKB_CB(skb)->family = AF_INET6;
 	XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct ipv6hdr, daddr);
 	return xfrm_input(skb, nexthdr, spi, 0);
@@ -48,13 +50,18 @@ int xfrm6_transport_finish(struct sk_buf
 	return -1;
 }
 
-int xfrm6_rcv(struct sk_buff *skb)
+int xfrm6_rcv_tnl(struct sk_buff *skb, struct ip6_tnl *t)
 {
 	return xfrm6_rcv_spi(skb, skb_network_header(skb)[IP6CB(skb)->nhoff],
-			     0);
+			     0, t);
 }
-EXPORT_SYMBOL(xfrm6_rcv);
+EXPORT_SYMBOL(xfrm6_rcv_tnl);
 
+int xfrm6_rcv(struct sk_buff *skb)
+{
+	return xfrm6_rcv_tnl(skb, NULL);
+}
+EXPORT_SYMBOL(xfrm6_rcv);
 int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
 		     xfrm_address_t *saddr, u8 proto)
 {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/ipv6/xfrm6_tunnel.c linux-libre-4.4.223-gnu/net/ipv6/xfrm6_tunnel.c
--- linux-libre-4.4.222-gnu/net/ipv6/xfrm6_tunnel.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/ipv6/xfrm6_tunnel.c	2020-05-10 04:26:37.000000000 -0400
@@ -239,7 +239,7 @@ static int xfrm6_tunnel_rcv(struct sk_bu
 	__be32 spi;
 
 	spi = xfrm6_tunnel_spi_lookup(net, (const xfrm_address_t *)&iph->saddr);
-	return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi);
+	return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi, NULL);
 }
 
 static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/irda/af_irda.c linux-libre-4.4.223-gnu/net/irda/af_irda.c
--- linux-libre-4.4.222-gnu/net/irda/af_irda.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/irda/af_irda.c	2020-05-10 04:26:37.000000000 -0400
@@ -839,7 +839,7 @@ static int irda_accept(struct socket *so
 	struct sock *sk = sock->sk;
 	struct irda_sock *new, *self = irda_sk(sk);
 	struct sock *newsk;
-	struct sk_buff *skb;
+	struct sk_buff *skb = NULL;
 	int err;
 
 	err = irda_create(sock_net(sk), newsock, sk->sk_protocol, 0);
@@ -907,7 +907,6 @@ static int irda_accept(struct socket *so
 	err = -EPERM; /* value does not seem to make sense. -arnd */
 	if (!new->tsap) {
 		pr_debug("%s(), dup failed!\n", __func__);
-		kfree_skb(skb);
 		goto out;
 	}
 
@@ -926,7 +925,6 @@ static int irda_accept(struct socket *so
 	/* Clean up the original one to keep it in listen state */
 	irttp_listen(self->tsap);
 
-	kfree_skb(skb);
 	sk->sk_ack_backlog--;
 
 	newsock->state = SS_CONNECTED;
@@ -934,6 +932,7 @@ static int irda_accept(struct socket *so
 	irda_connect_response(new);
 	err = 0;
 out:
+	kfree_skb(skb);
 	release_sock(sk);
 	return err;
 }
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/l2tp/l2tp_core.c linux-libre-4.4.223-gnu/net/l2tp/l2tp_core.c
--- linux-libre-4.4.222-gnu/net/l2tp/l2tp_core.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/l2tp/l2tp_core.c	2020-05-10 04:26:37.000000000 -0400
@@ -1953,6 +1953,9 @@ static __net_exit void l2tp_exit_net(str
 		l2tp_tunnel_delete(tunnel);
 	}
 	rcu_read_unlock_bh();
+
+	flush_workqueue(l2tp_wq);
+	rcu_barrier();
 }
 
 static struct pernet_operations l2tp_net_ops = {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/mac80211/ieee80211_i.h linux-libre-4.4.223-gnu/net/mac80211/ieee80211_i.h
--- linux-libre-4.4.222-gnu/net/mac80211/ieee80211_i.h	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/mac80211/ieee80211_i.h	2020-05-10 04:26:37.000000000 -0400
@@ -1706,6 +1706,10 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(stru
 enum ieee80211_sta_rx_bandwidth ieee80211_sta_cap_rx_bw(struct sta_info *sta);
 enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta);
 void ieee80211_sta_set_rx_nss(struct sta_info *sta);
+enum ieee80211_sta_rx_bandwidth
+ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width);
+enum nl80211_chan_width ieee80211_sta_cap_chan_bw(struct sta_info *sta);
+void ieee80211_sta_set_rx_nss(struct sta_info *sta);
 u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
                                   struct sta_info *sta, u8 opmode,
 				  enum ieee80211_band band);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/mac80211/mlme.c linux-libre-4.4.223-gnu/net/mac80211/mlme.c
--- linux-libre-4.4.222-gnu/net/mac80211/mlme.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/mac80211/mlme.c	2020-05-10 04:26:37.000000000 -0400
@@ -2283,7 +2283,7 @@ void ieee80211_sta_tx_notify(struct ieee
 	if (!ieee80211_is_data(hdr->frame_control))
 	    return;
 
-	if (ieee80211_is_nullfunc(hdr->frame_control) &&
+	if (ieee80211_is_any_nullfunc(hdr->frame_control) &&
 	    sdata->u.mgd.probe_send_count > 0) {
 		if (ack)
 			ieee80211_sta_reset_conn_monitor(sdata);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/mac80211/offchannel.c linux-libre-4.4.223-gnu/net/mac80211/offchannel.c
--- linux-libre-4.4.222-gnu/net/mac80211/offchannel.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/mac80211/offchannel.c	2020-05-10 04:26:37.000000000 -0400
@@ -308,11 +308,10 @@ void ieee80211_roc_notify_destroy(struct
 
 	/* was never transmitted */
 	if (roc->frame) {
-		cfg80211_mgmt_tx_status(&roc->sdata->wdev,
-					(unsigned long)roc->frame,
+		cfg80211_mgmt_tx_status(&roc->sdata->wdev, roc->mgmt_tx_cookie,
 					roc->frame->data, roc->frame->len,
 					false, GFP_KERNEL);
-		kfree_skb(roc->frame);
+		ieee80211_free_txskb(&roc->sdata->local->hw, roc->frame);
 	}
 
 	if (!roc->mgmt_tx_cookie)
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/mac80211/rx.c linux-libre-4.4.223-gnu/net/mac80211/rx.c
--- linux-libre-4.4.222-gnu/net/mac80211/rx.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/mac80211/rx.c	2020-05-10 04:26:37.000000000 -0400
@@ -1110,8 +1110,7 @@ ieee80211_rx_h_check_dup(struct ieee8021
 		return RX_CONTINUE;
 
 	if (ieee80211_is_ctl(hdr->frame_control) ||
-	    ieee80211_is_nullfunc(hdr->frame_control) ||
-	    ieee80211_is_qos_nullfunc(hdr->frame_control) ||
+	    ieee80211_is_any_nullfunc(hdr->frame_control) ||
 	    is_multicast_ether_addr(hdr->addr1))
 		return RX_CONTINUE;
 
@@ -1487,8 +1486,7 @@ ieee80211_rx_h_sta_process(struct ieee80
 	 * Drop (qos-)data::nullfunc frames silently, since they
 	 * are used only to control station power saving mode.
 	 */
-	if (ieee80211_is_nullfunc(hdr->frame_control) ||
-	    ieee80211_is_qos_nullfunc(hdr->frame_control)) {
+	if (ieee80211_is_any_nullfunc(hdr->frame_control)) {
 		I802_DEBUG_INC(rx->local->rx_handlers_drop_nullfunc);
 
 		/*
@@ -1977,7 +1975,7 @@ static int ieee80211_drop_unencrypted(st
 
 	/* Drop unencrypted frames if key is set. */
 	if (unlikely(!ieee80211_has_protected(fc) &&
-		     !ieee80211_is_nullfunc(fc) &&
+		     !ieee80211_is_any_nullfunc(fc) &&
 		     ieee80211_is_data(fc) && rx->key))
 		return -EACCES;
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/mac80211/status.c linux-libre-4.4.223-gnu/net/mac80211/status.c
--- linux-libre-4.4.222-gnu/net/mac80211/status.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/mac80211/status.c	2020-05-10 04:26:37.000000000 -0400
@@ -474,8 +474,7 @@ static void ieee80211_report_ack_skb(str
 		rcu_read_lock();
 		sdata = ieee80211_sdata_from_skb(local, skb);
 		if (sdata) {
-			if (ieee80211_is_nullfunc(hdr->frame_control) ||
-			    ieee80211_is_qos_nullfunc(hdr->frame_control))
+			if (ieee80211_is_any_nullfunc(hdr->frame_control))
 				cfg80211_probe_status(sdata->dev, hdr->addr1,
 						      cookie, acked,
 						      GFP_ATOMIC);
@@ -905,7 +904,7 @@ void ieee80211_tx_status(struct ieee8021
 			I802_DEBUG_INC(local->dot11FailedCount);
 	}
 
-	if (ieee80211_is_nullfunc(fc) && ieee80211_has_pm(fc) &&
+	if (ieee80211_is_any_nullfunc(fc) && ieee80211_has_pm(fc) &&
 	    ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS) &&
 	    !(info->flags & IEEE80211_TX_CTL_INJECTED) &&
 	    local->ps_sdata && !(local->scanning)) {
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/mac80211/tdls.c linux-libre-4.4.223-gnu/net/mac80211/tdls.c
--- linux-libre-4.4.222-gnu/net/mac80211/tdls.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/mac80211/tdls.c	2020-05-10 04:26:37.000000000 -0400
@@ -4,7 +4,7 @@
  * Copyright 2006-2010	Johannes Berg <johannes@sipsolutions.net>
  * Copyright 2014, Intel Corporation
  * Copyright 2014  Intel Mobile Communications GmbH
- * Copyright 2015  Intel Deutschland GmbH
+ * Copyright 2015 - 2016 Intel Deutschland GmbH
  *
  * This file is GPLv2 as found in COPYING.
  */
@@ -15,6 +15,7 @@
 #include <linux/rtnetlink.h>
 #include "ieee80211_i.h"
 #include "driver-ops.h"
+#include "rate.h"
 
 /* give usermode some time for retries in setting up the TDLS session */
 #define TDLS_PEER_SETUP_TIMEOUT	(15 * HZ)
@@ -302,7 +303,7 @@ ieee80211_tdls_chandef_vht_upgrade(struc
 	/* IEEE802.11ac-2013 Table E-4 */
 	u16 centers_80mhz[] = { 5210, 5290, 5530, 5610, 5690, 5775 };
 	struct cfg80211_chan_def uc = sta->tdls_chandef;
-	enum nl80211_chan_width max_width = ieee80211_get_sta_bw(&sta->sta);
+	enum nl80211_chan_width max_width = ieee80211_sta_cap_chan_bw(sta);
 	int i;
 
 	/* only support upgrading non-narrow channels up to 80Mhz */
@@ -313,7 +314,7 @@ ieee80211_tdls_chandef_vht_upgrade(struc
 	if (max_width > NL80211_CHAN_WIDTH_80)
 		max_width = NL80211_CHAN_WIDTH_80;
 
-	if (uc.width == max_width)
+	if (uc.width >= max_width)
 		return;
 	/*
 	 * Channel usage constrains in the IEEE802.11ac-2013 specification only
@@ -324,6 +325,7 @@ ieee80211_tdls_chandef_vht_upgrade(struc
 	for (i = 0; i < ARRAY_SIZE(centers_80mhz); i++)
 		if (abs(uc.chan->center_freq - centers_80mhz[i]) <= 30) {
 			uc.center_freq1 = centers_80mhz[i];
+			uc.center_freq2 = 0;
 			uc.width = NL80211_CHAN_WIDTH_80;
 			break;
 		}
@@ -332,7 +334,7 @@ ieee80211_tdls_chandef_vht_upgrade(struc
 		return;
 
 	/* proceed to downgrade the chandef until usable or the same */
-	while (uc.width > max_width &&
+	while (uc.width > max_width ||
 	       !cfg80211_reg_can_beacon_relax(sdata->local->hw.wiphy, &uc,
 					      sdata->wdev.iftype))
 		ieee80211_chandef_downgrade(&uc);
@@ -1242,18 +1244,44 @@ int ieee80211_tdls_mgmt(struct wiphy *wi
 	return ret;
 }
 
-static void iee80211_tdls_recalc_chanctx(struct ieee80211_sub_if_data *sdata)
+static void iee80211_tdls_recalc_chanctx(struct ieee80211_sub_if_data *sdata,
+					 struct sta_info *sta)
 {
 	struct ieee80211_local *local = sdata->local;
 	struct ieee80211_chanctx_conf *conf;
 	struct ieee80211_chanctx *ctx;
+	enum nl80211_chan_width width;
+	struct ieee80211_supported_band *sband;
 
 	mutex_lock(&local->chanctx_mtx);
 	conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
 					 lockdep_is_held(&local->chanctx_mtx));
 	if (conf) {
+		width = conf->def.width;
+		sband = local->hw.wiphy->bands[conf->def.chan->band];
 		ctx = container_of(conf, struct ieee80211_chanctx, conf);
 		ieee80211_recalc_chanctx_chantype(local, ctx);
+
+		/* if width changed and a peer is given, update its BW */
+		if (width != conf->def.width && sta &&
+		    test_sta_flag(sta, WLAN_STA_TDLS_WIDER_BW)) {
+			enum ieee80211_sta_rx_bandwidth bw;
+
+			bw = ieee80211_chan_width_to_rx_bw(conf->def.width);
+			bw = min(bw, ieee80211_sta_cap_rx_bw(sta));
+			if (bw != sta->sta.bandwidth) {
+				sta->sta.bandwidth = bw;
+				rate_control_rate_update(local, sband, sta,
+							 IEEE80211_RC_BW_CHANGED);
+				/*
+				 * if a TDLS peer BW was updated, we need to
+				 * recalc the chandef width again, to get the
+				 * correct chanctx min_def
+				 */
+				ieee80211_recalc_chanctx_chantype(local, ctx);
+			}
+		}
+
 	}
 	mutex_unlock(&local->chanctx_mtx);
 }
@@ -1350,8 +1378,6 @@ int ieee80211_tdls_oper(struct wiphy *wi
 			break;
 		}
 
-		iee80211_tdls_recalc_chanctx(sdata);
-
 		mutex_lock(&local->sta_mtx);
 		sta = sta_info_get(sdata, peer);
 		if (!sta) {
@@ -1360,6 +1386,7 @@ int ieee80211_tdls_oper(struct wiphy *wi
 			break;
 		}
 
+		iee80211_tdls_recalc_chanctx(sdata, sta);
 		iee80211_tdls_recalc_ht_protection(sdata, sta);
 
 		set_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH);
@@ -1390,7 +1417,7 @@ int ieee80211_tdls_oper(struct wiphy *wi
 		iee80211_tdls_recalc_ht_protection(sdata, NULL);
 		mutex_unlock(&local->sta_mtx);
 
-		iee80211_tdls_recalc_chanctx(sdata);
+		iee80211_tdls_recalc_chanctx(sdata, NULL);
 		break;
 	default:
 		ret = -ENOTSUPP;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/mac80211/tx.c linux-libre-4.4.223-gnu/net/mac80211/tx.c
--- linux-libre-4.4.222-gnu/net/mac80211/tx.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/mac80211/tx.c	2020-05-10 04:26:37.000000000 -0400
@@ -291,7 +291,7 @@ ieee80211_tx_h_check_assoc(struct ieee80
 	if (unlikely(test_bit(SCAN_SW_SCANNING, &tx->local->scanning)) &&
 	    test_bit(SDATA_STATE_OFFCHANNEL, &tx->sdata->state) &&
 	    !ieee80211_is_probe_req(hdr->frame_control) &&
-	    !ieee80211_is_nullfunc(hdr->frame_control))
+	    !ieee80211_is_any_nullfunc(hdr->frame_control))
 		/*
 		 * When software scanning only nullfunc frames (to notify
 		 * the sleep state to the AP) and probe requests (for the
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/mac80211/vht.c linux-libre-4.4.223-gnu/net/mac80211/vht.c
--- linux-libre-4.4.222-gnu/net/mac80211/vht.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/mac80211/vht.c	2020-05-10 04:26:37.000000000 -0400
@@ -299,7 +299,30 @@ enum ieee80211_sta_rx_bandwidth ieee8021
 	return IEEE80211_STA_RX_BW_80;
 }
 
-static enum ieee80211_sta_rx_bandwidth
+enum nl80211_chan_width ieee80211_sta_cap_chan_bw(struct sta_info *sta)
+{
+	struct ieee80211_sta_vht_cap *vht_cap = &sta->sta.vht_cap;
+	u32 cap_width;
+
+	if (!vht_cap->vht_supported) {
+		if (!sta->sta.ht_cap.ht_supported)
+			return NL80211_CHAN_WIDTH_20_NOHT;
+
+		return sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ?
+				NL80211_CHAN_WIDTH_40 : NL80211_CHAN_WIDTH_20;
+	}
+
+	cap_width = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
+
+	if (cap_width == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ)
+		return NL80211_CHAN_WIDTH_160;
+	else if (cap_width == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
+		return NL80211_CHAN_WIDTH_80P80;
+
+	return NL80211_CHAN_WIDTH_80;
+}
+
+enum ieee80211_sta_rx_bandwidth
 ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width)
 {
 	switch (width) {
@@ -327,10 +350,7 @@ enum ieee80211_sta_rx_bandwidth ieee8021
 
 	bw = ieee80211_sta_cap_rx_bw(sta);
 	bw = min(bw, sta->cur_max_bandwidth);
-
-	/* do not cap the BW of TDLS WIDER_BW peers by the bss */
-	if (!test_sta_flag(sta, WLAN_STA_TDLS_WIDER_BW))
-		bw = min(bw, ieee80211_chan_width_to_rx_bw(bss_width));
+	bw = min(bw, ieee80211_chan_width_to_rx_bw(bss_width));
 
 	return bw;
 }
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/netfilter/nfnetlink.c linux-libre-4.4.223-gnu/net/netfilter/nfnetlink.c
--- linux-libre-4.4.222-gnu/net/netfilter/nfnetlink.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/netfilter/nfnetlink.c	2020-05-10 04:26:37.000000000 -0400
@@ -309,14 +309,14 @@ replay:
 #endif
 		{
 			nfnl_unlock(subsys_id);
-			netlink_ack(skb, nlh, -EOPNOTSUPP);
+			netlink_ack(oskb, nlh, -EOPNOTSUPP);
 			return kfree_skb(skb);
 		}
 	}
 
 	if (!ss->commit || !ss->abort) {
 		nfnl_unlock(subsys_id);
-		netlink_ack(skb, nlh, -EOPNOTSUPP);
+		netlink_ack(oskb, nlh, -EOPNOTSUPP);
 		return kfree_skb(skb);
 	}
 
@@ -406,7 +406,7 @@ ack:
 				 * pointing to the batch header.
 				 */
 				nfnl_err_reset(&err_list);
-				netlink_ack(skb, nlmsg_hdr(oskb), -ENOMEM);
+				netlink_ack(oskb, nlmsg_hdr(oskb), -ENOMEM);
 				status |= NFNL_BATCH_FAILURE;
 				goto done;
 			}
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/netfilter/nf_tables_api.c linux-libre-4.4.223-gnu/net/netfilter/nf_tables_api.c
--- linux-libre-4.4.222-gnu/net/netfilter/nf_tables_api.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/netfilter/nf_tables_api.c	2020-05-10 04:26:37.000000000 -0400
@@ -2849,12 +2849,14 @@ static int nf_tables_newset(struct net *
 
 	err = nft_trans_set_add(&ctx, NFT_MSG_NEWSET, set);
 	if (err < 0)
-		goto err2;
+		goto err3;
 
 	list_add_tail_rcu(&set->list, &table->sets);
 	table->use++;
 	return 0;
 
+err3:
+	ops->destroy(set);
 err2:
 	kfree(set);
 err1:
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/netfilter/nf_tables_core.c linux-libre-4.4.223-gnu/net/netfilter/nf_tables_core.c
--- linux-libre-4.4.222-gnu/net/netfilter/nf_tables_core.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/netfilter/nf_tables_core.c	2020-05-10 04:26:37.000000000 -0400
@@ -130,7 +130,7 @@ next_rule:
 	list_for_each_entry_continue_rcu(rule, &chain->rules, list) {
 
 		/* This rule is not active, skip. */
-		if (unlikely(rule->genmask & (1 << gencursor)))
+		if (unlikely(rule->genmask & gencursor))
 			continue;
 
 		rulenum++;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/netfilter/nft_dynset.c linux-libre-4.4.223-gnu/net/netfilter/nft_dynset.c
--- linux-libre-4.4.222-gnu/net/netfilter/nft_dynset.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/netfilter/nft_dynset.c	2020-05-10 04:26:37.000000000 -0400
@@ -121,6 +121,9 @@ static int nft_dynset_init(const struct
 			return PTR_ERR(set);
 	}
 
+	if (set->ops->update == NULL)
+		return -EOPNOTSUPP;
+
 	if (set->flags & NFT_SET_CONSTANT)
 		return -EBUSY;
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/nfc/nci/core.c linux-libre-4.4.223-gnu/net/nfc/nci/core.c
--- linux-libre-4.4.222-gnu/net/nfc/nci/core.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/nfc/nci/core.c	2020-05-10 04:26:37.000000000 -0400
@@ -610,14 +610,14 @@ int nci_core_conn_create(struct nci_dev
 	struct nci_core_conn_create_cmd *cmd;
 	struct core_conn_create_data data;
 
+	if (!number_destination_params)
+		return -EINVAL;
+
 	data.length = params_len + sizeof(struct nci_core_conn_create_cmd);
 	cmd = kzalloc(data.length, GFP_KERNEL);
 	if (!cmd)
 		return -ENOMEM;
 
-	if (!number_destination_params)
-		return -EINVAL;
-
 	cmd->destination_type = destination_type;
 	cmd->number_destination_params = number_destination_params;
 	memcpy(cmd->params, params, params_len);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/openvswitch/actions.c linux-libre-4.4.223-gnu/net/openvswitch/actions.c
--- linux-libre-4.4.222-gnu/net/openvswitch/actions.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/openvswitch/actions.c	2020-05-10 04:26:37.000000000 -0400
@@ -137,11 +137,23 @@ static bool is_flow_key_valid(const stru
 	return !!key->eth.type;
 }
 
+static void update_ethertype(struct sk_buff *skb, struct ethhdr *hdr,
+			     __be16 ethertype)
+{
+	if (skb->ip_summed == CHECKSUM_COMPLETE) {
+		__be16 diff[] = { ~(hdr->h_proto), ethertype };
+
+		skb->csum = ~csum_partial((char *)diff, sizeof(diff),
+					~skb->csum);
+	}
+
+	hdr->h_proto = ethertype;
+}
+
 static int push_mpls(struct sk_buff *skb, struct sw_flow_key *key,
 		     const struct ovs_action_push_mpls *mpls)
 {
 	__be32 *new_mpls_lse;
-	struct ethhdr *hdr;
 
 	/* Networking stack do not allow simultaneous Tunnel and MPLS GSO. */
 	if (skb->encapsulation)
@@ -160,9 +172,7 @@ static int push_mpls(struct sk_buff *skb
 
 	skb_postpush_rcsum(skb, new_mpls_lse, MPLS_HLEN);
 
-	hdr = eth_hdr(skb);
-	hdr->h_proto = mpls->mpls_ethertype;
-
+	update_ethertype(skb, eth_hdr(skb), mpls->mpls_ethertype);
 	if (!skb->inner_protocol)
 		skb_set_inner_protocol(skb, skb->protocol);
 	skb->protocol = mpls->mpls_ethertype;
@@ -193,7 +203,7 @@ static int pop_mpls(struct sk_buff *skb,
 	 * field correctly in the presence of VLAN tags.
 	 */
 	hdr = (struct ethhdr *)(skb_mpls_header(skb) - ETH_HLEN);
-	hdr->h_proto = ethertype;
+	update_ethertype(skb, hdr, ethertype);
 	if (eth_p_mpls(skb->protocol))
 		skb->protocol = ethertype;
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/rds/tcp.c linux-libre-4.4.223-gnu/net/rds/tcp.c
--- linux-libre-4.4.222-gnu/net/rds/tcp.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/rds/tcp.c	2020-05-10 04:26:37.000000000 -0400
@@ -110,7 +110,7 @@ void rds_tcp_restore_callbacks(struct so
 
 /*
  * This is the only path that sets tc->t_sock.  Send and receive trust that
- * it is set.  The RDS_CONN_CONNECTED bit protects those paths from being
+ * it is set.  The RDS_CONN_UP bit protects those paths from being
  * called while it isn't set.
  */
 void rds_tcp_set_callbacks(struct socket *sock, struct rds_connection *conn)
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/rds/tcp_listen.c linux-libre-4.4.223-gnu/net/rds/tcp_listen.c
--- linux-libre-4.4.222-gnu/net/rds/tcp_listen.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/rds/tcp_listen.c	2020-05-10 04:26:37.000000000 -0400
@@ -115,24 +115,32 @@ int rds_tcp_accept_one(struct socket *so
 	 * rds_tcp_state_change() will do that cleanup
 	 */
 	rs_tcp = (struct rds_tcp_connection *)conn->c_transport_data;
-	if (rs_tcp->t_sock &&
-	    ntohl(inet->inet_saddr) < ntohl(inet->inet_daddr)) {
-		struct sock *nsk = new_sock->sk;
+	rds_conn_transition(conn, RDS_CONN_DOWN, RDS_CONN_CONNECTING);
+	if (rs_tcp->t_sock) {
+		/* Need to resolve a duelling SYN between peers.
+		 * We have an outstanding SYN to this peer, which may
+		 * potentially have transitioned to the RDS_CONN_UP state,
+		 * so we must quiesce any send threads before resetting
+		 * c_transport_data.
+		 */
+		wait_event(conn->c_waitq,
+			   !test_bit(RDS_IN_XMIT, &conn->c_flags));
+		if (ntohl(inet->inet_saddr) < ntohl(inet->inet_daddr)) {
+			struct sock *nsk = new_sock->sk;
 
-		nsk->sk_user_data = NULL;
-		nsk->sk_prot->disconnect(nsk, 0);
-		tcp_done(nsk);
-		new_sock = NULL;
-		ret = 0;
-		goto out;
-	} else if (rs_tcp->t_sock) {
-		rds_tcp_restore_callbacks(rs_tcp->t_sock, rs_tcp);
-		conn->c_outgoing = 0;
+			nsk->sk_user_data = NULL;
+			nsk->sk_prot->disconnect(nsk, 0);
+			tcp_done(nsk);
+			new_sock = NULL;
+			ret = 0;
+			goto out;
+		} else if (rs_tcp->t_sock) {
+			rds_tcp_restore_callbacks(rs_tcp->t_sock, rs_tcp);
+			conn->c_outgoing = 0;
+		}
 	}
-
-	rds_conn_transition(conn, RDS_CONN_DOWN, RDS_CONN_CONNECTING);
 	rds_tcp_set_callbacks(new_sock, conn);
-	rds_connect_complete(conn);
+	rds_connect_complete(conn); /* marks RDS_CONN_UP */
 	new_sock = NULL;
 	ret = 0;
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/sched/cls_bpf.c linux-libre-4.4.223-gnu/net/sched/cls_bpf.c
--- linux-libre-4.4.222-gnu/net/sched/cls_bpf.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/sched/cls_bpf.c	2020-05-10 04:26:37.000000000 -0400
@@ -107,8 +107,9 @@ static int cls_bpf_classify(struct sk_bu
 		}
 
 		if (prog->exts_integrated) {
-			res->class = prog->res.class;
-			res->classid = qdisc_skb_cb(skb)->tc_classid;
+			res->class   = 0;
+			res->classid = TC_H_MAJ(prog->res.classid) |
+				       qdisc_skb_cb(skb)->tc_classid;
 
 			ret = cls_bpf_exec_opcode(filter_res);
 			if (ret == TC_ACT_UNSPEC)
@@ -118,10 +119,12 @@ static int cls_bpf_classify(struct sk_bu
 
 		if (filter_res == 0)
 			continue;
-
-		*res = prog->res;
-		if (filter_res != -1)
+		if (filter_res != -1) {
+			res->class   = 0;
 			res->classid = filter_res;
+		} else {
+			*res = prog->res;
+		}
 
 		ret = tcf_exts_exec(skb, &prog->exts, res);
 		if (ret < 0)
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/sched/cls_flower.c linux-libre-4.4.223-gnu/net/sched/cls_flower.c
--- linux-libre-4.4.222-gnu/net/sched/cls_flower.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/sched/cls_flower.c	2020-05-10 04:26:37.000000000 -0400
@@ -351,12 +351,10 @@ static int fl_init_hashtable(struct cls_
 
 #define FL_KEY_MEMBER_OFFSET(member) offsetof(struct fl_flow_key, member)
 #define FL_KEY_MEMBER_SIZE(member) (sizeof(((struct fl_flow_key *) 0)->member))
-#define FL_KEY_MEMBER_END_OFFSET(member)					\
-	(FL_KEY_MEMBER_OFFSET(member) + FL_KEY_MEMBER_SIZE(member))
 
-#define FL_KEY_IN_RANGE(mask, member)						\
-        (FL_KEY_MEMBER_OFFSET(member) <= (mask)->range.end &&			\
-         FL_KEY_MEMBER_END_OFFSET(member) >= (mask)->range.start)
+#define FL_KEY_IS_MASKED(mask, member)						\
+	memchr_inv(((char *)mask) + FL_KEY_MEMBER_OFFSET(member),		\
+		   0, FL_KEY_MEMBER_SIZE(member))				\
 
 #define FL_KEY_SET(keys, cnt, id, member)					\
 	do {									\
@@ -365,9 +363,9 @@ static int fl_init_hashtable(struct cls_
 		cnt++;								\
 	} while(0);
 
-#define FL_KEY_SET_IF_IN_RANGE(mask, keys, cnt, id, member)			\
+#define FL_KEY_SET_IF_MASKED(mask, keys, cnt, id, member)			\
 	do {									\
-		if (FL_KEY_IN_RANGE(mask, member))				\
+		if (FL_KEY_IS_MASKED(mask, member))				\
 			FL_KEY_SET(keys, cnt, id, member);			\
 	} while(0);
 
@@ -379,14 +377,14 @@ static void fl_init_dissector(struct cls
 
 	FL_KEY_SET(keys, cnt, FLOW_DISSECTOR_KEY_CONTROL, control);
 	FL_KEY_SET(keys, cnt, FLOW_DISSECTOR_KEY_BASIC, basic);
-	FL_KEY_SET_IF_IN_RANGE(mask, keys, cnt,
-			       FLOW_DISSECTOR_KEY_ETH_ADDRS, eth);
-	FL_KEY_SET_IF_IN_RANGE(mask, keys, cnt,
-			       FLOW_DISSECTOR_KEY_IPV4_ADDRS, ipv4);
-	FL_KEY_SET_IF_IN_RANGE(mask, keys, cnt,
-			       FLOW_DISSECTOR_KEY_IPV6_ADDRS, ipv6);
-	FL_KEY_SET_IF_IN_RANGE(mask, keys, cnt,
-			       FLOW_DISSECTOR_KEY_PORTS, tp);
+	FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
+			     FLOW_DISSECTOR_KEY_ETH_ADDRS, eth);
+	FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
+			     FLOW_DISSECTOR_KEY_IPV4_ADDRS, ipv4);
+	FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
+			     FLOW_DISSECTOR_KEY_IPV6_ADDRS, ipv6);
+	FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
+			     FLOW_DISSECTOR_KEY_PORTS, tp);
 
 	skb_flow_dissector_init(&head->dissector, keys, cnt);
 }
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/sched/sch_drr.c linux-libre-4.4.223-gnu/net/sched/sch_drr.c
--- linux-libre-4.4.222-gnu/net/sched/sch_drr.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/sched/sch_drr.c	2020-05-10 04:26:37.000000000 -0400
@@ -375,6 +375,7 @@ static int drr_enqueue(struct sk_buff *s
 		cl->deficit = cl->quantum;
 	}
 
+	qdisc_qstats_backlog_inc(sch, skb);
 	sch->q.qlen++;
 	return err;
 }
@@ -405,6 +406,7 @@ static struct sk_buff *drr_dequeue(struc
 
 			bstats_update(&cl->bstats, skb);
 			qdisc_bstats_update(sch, skb);
+			qdisc_qstats_backlog_dec(sch, skb);
 			sch->q.qlen--;
 			return skb;
 		}
@@ -426,6 +428,7 @@ static unsigned int drr_drop(struct Qdis
 		if (cl->qdisc->ops->drop) {
 			len = cl->qdisc->ops->drop(cl->qdisc);
 			if (len > 0) {
+				sch->qstats.backlog -= len;
 				sch->q.qlen--;
 				if (cl->qdisc->q.qlen == 0)
 					list_del(&cl->alist);
@@ -461,6 +464,7 @@ static void drr_reset_qdisc(struct Qdisc
 			qdisc_reset(cl->qdisc);
 		}
 	}
+	sch->qstats.backlog = 0;
 	sch->q.qlen = 0;
 }
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/sched/sch_fq.c linux-libre-4.4.223-gnu/net/sched/sch_fq.c
--- linux-libre-4.4.222-gnu/net/sched/sch_fq.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/sched/sch_fq.c	2020-05-10 04:26:37.000000000 -0400
@@ -830,20 +830,24 @@ nla_put_failure:
 static int fq_dump_stats(struct Qdisc *sch, struct gnet_dump *d)
 {
 	struct fq_sched_data *q = qdisc_priv(sch);
-	u64 now = ktime_get_ns();
-	struct tc_fq_qd_stats st = {
-		.gc_flows		= q->stat_gc_flows,
-		.highprio_packets	= q->stat_internal_packets,
-		.tcp_retrans		= q->stat_tcp_retrans,
-		.throttled		= q->stat_throttled,
-		.flows_plimit		= q->stat_flows_plimit,
-		.pkts_too_long		= q->stat_pkts_too_long,
-		.allocation_errors	= q->stat_allocation_errors,
-		.flows			= q->flows,
-		.inactive_flows		= q->inactive_flows,
-		.throttled_flows	= q->throttled_flows,
-		.time_next_delayed_flow	= q->time_next_delayed_flow - now,
-	};
+	struct tc_fq_qd_stats st;
+
+	sch_tree_lock(sch);
+
+	st.gc_flows		  = q->stat_gc_flows;
+	st.highprio_packets	  = q->stat_internal_packets;
+	st.tcp_retrans		  = q->stat_tcp_retrans;
+	st.throttled		  = q->stat_throttled;
+	st.flows_plimit		  = q->stat_flows_plimit;
+	st.pkts_too_long	  = q->stat_pkts_too_long;
+	st.allocation_errors	  = q->stat_allocation_errors;
+	st.time_next_delayed_flow = q->time_next_delayed_flow - ktime_get_ns();
+	st.flows		  = q->flows;
+	st.inactive_flows	  = q->inactive_flows;
+	st.throttled_flows	  = q->throttled_flows;
+	st.pad			  = 0;
+
+	sch_tree_unlock(sch);
 
 	return gnet_stats_copy_app(d, &st, sizeof(st));
 }
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/sched/sch_fq_codel.c linux-libre-4.4.223-gnu/net/sched/sch_fq_codel.c
--- linux-libre-4.4.222-gnu/net/sched/sch_fq_codel.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/sched/sch_fq_codel.c	2020-05-10 04:26:37.000000000 -0400
@@ -588,7 +588,7 @@ static int fq_codel_dump_class_stats(str
 		qs.backlog = q->backlogs[idx];
 		qs.drops = flow->dropped;
 	}
-	if (gnet_stats_copy_queue(d, NULL, &qs, 0) < 0)
+	if (gnet_stats_copy_queue(d, NULL, &qs, qs.qlen) < 0)
 		return -1;
 	if (idx < q->flows_cnt)
 		return gnet_stats_copy_app(d, &xstats, sizeof(xstats));
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/sched/sch_generic.c linux-libre-4.4.223-gnu/net/sched/sch_generic.c
--- linux-libre-4.4.222-gnu/net/sched/sch_generic.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/sched/sch_generic.c	2020-05-10 04:26:37.000000000 -0400
@@ -49,6 +49,7 @@ static inline int dev_requeue_skb(struct
 {
 	q->gso_skb = skb;
 	q->qstats.requeues++;
+	qdisc_qstats_backlog_inc(q, skb);
 	q->q.qlen++;	/* it's still part of the queue */
 	__netif_schedule(q);
 
@@ -92,6 +93,7 @@ static struct sk_buff *dequeue_skb(struc
 		txq = skb_get_tx_queue(txq->dev, skb);
 		if (!netif_xmit_frozen_or_stopped(txq)) {
 			q->gso_skb = NULL;
+			qdisc_qstats_backlog_dec(q, skb);
 			q->q.qlen--;
 		} else
 			skb = NULL;
@@ -624,18 +626,19 @@ struct Qdisc *qdisc_create_dflt(struct n
 	struct Qdisc *sch;
 
 	if (!try_module_get(ops->owner))
-		goto errout;
+		return NULL;
 
 	sch = qdisc_alloc(dev_queue, ops);
-	if (IS_ERR(sch))
-		goto errout;
+	if (IS_ERR(sch)) {
+		module_put(ops->owner);
+		return NULL;
+	}
 	sch->parent = parentid;
 
 	if (!ops->init || ops->init(sch, NULL) == 0)
 		return sch;
 
 	qdisc_destroy(sch);
-errout:
 	return NULL;
 }
 EXPORT_SYMBOL(qdisc_create_dflt);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/sched/sch_hfsc.c linux-libre-4.4.223-gnu/net/sched/sch_hfsc.c
--- linux-libre-4.4.222-gnu/net/sched/sch_hfsc.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/sched/sch_hfsc.c	2020-05-10 04:26:37.000000000 -0400
@@ -1529,6 +1529,7 @@ hfsc_reset_qdisc(struct Qdisc *sch)
 	q->eligible = RB_ROOT;
 	INIT_LIST_HEAD(&q->droplist);
 	qdisc_watchdog_cancel(&q->watchdog);
+	sch->qstats.backlog = 0;
 	sch->q.qlen = 0;
 }
 
@@ -1559,14 +1560,6 @@ hfsc_dump_qdisc(struct Qdisc *sch, struc
 	struct hfsc_sched *q = qdisc_priv(sch);
 	unsigned char *b = skb_tail_pointer(skb);
 	struct tc_hfsc_qopt qopt;
-	struct hfsc_class *cl;
-	unsigned int i;
-
-	sch->qstats.backlog = 0;
-	for (i = 0; i < q->clhash.hashsize; i++) {
-		hlist_for_each_entry(cl, &q->clhash.hash[i], cl_common.hnode)
-			sch->qstats.backlog += cl->qdisc->qstats.backlog;
-	}
 
 	qopt.defcls = q->defcls;
 	if (nla_put(skb, TCA_OPTIONS, sizeof(qopt), &qopt))
@@ -1604,6 +1597,7 @@ hfsc_enqueue(struct sk_buff *skb, struct
 	if (cl->qdisc->q.qlen == 1)
 		set_active(cl, qdisc_pkt_len(skb));
 
+	qdisc_qstats_backlog_inc(sch, skb);
 	sch->q.qlen++;
 
 	return NET_XMIT_SUCCESS;
@@ -1672,6 +1666,7 @@ hfsc_dequeue(struct Qdisc *sch)
 
 	qdisc_unthrottled(sch);
 	qdisc_bstats_update(sch, skb);
+	qdisc_qstats_backlog_dec(sch, skb);
 	sch->q.qlen--;
 
 	return skb;
@@ -1695,6 +1690,7 @@ hfsc_drop(struct Qdisc *sch)
 			}
 			cl->qstats.drops++;
 			qdisc_qstats_drop(sch);
+			sch->qstats.backlog -= len;
 			sch->q.qlen--;
 			return len;
 		}
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/sched/sch_prio.c linux-libre-4.4.223-gnu/net/sched/sch_prio.c
--- linux-libre-4.4.222-gnu/net/sched/sch_prio.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/sched/sch_prio.c	2020-05-10 04:26:37.000000000 -0400
@@ -85,6 +85,7 @@ prio_enqueue(struct sk_buff *skb, struct
 
 	ret = qdisc_enqueue(skb, qdisc);
 	if (ret == NET_XMIT_SUCCESS) {
+		qdisc_qstats_backlog_inc(sch, skb);
 		sch->q.qlen++;
 		return NET_XMIT_SUCCESS;
 	}
@@ -117,6 +118,7 @@ static struct sk_buff *prio_dequeue(stru
 		struct sk_buff *skb = qdisc_dequeue_peeked(qdisc);
 		if (skb) {
 			qdisc_bstats_update(sch, skb);
+			qdisc_qstats_backlog_dec(sch, skb);
 			sch->q.qlen--;
 			return skb;
 		}
@@ -135,6 +137,7 @@ static unsigned int prio_drop(struct Qdi
 	for (prio = q->bands-1; prio >= 0; prio--) {
 		qdisc = q->queues[prio];
 		if (qdisc->ops->drop && (len = qdisc->ops->drop(qdisc)) != 0) {
+			sch->qstats.backlog -= len;
 			sch->q.qlen--;
 			return len;
 		}
@@ -151,6 +154,7 @@ prio_reset(struct Qdisc *sch)
 
 	for (prio = 0; prio < q->bands; prio++)
 		qdisc_reset(q->queues[prio]);
+	sch->qstats.backlog = 0;
 	sch->q.qlen = 0;
 }
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/sched/sch_qfq.c linux-libre-4.4.223-gnu/net/sched/sch_qfq.c
--- linux-libre-4.4.222-gnu/net/sched/sch_qfq.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/sched/sch_qfq.c	2020-05-10 04:26:37.000000000 -0400
@@ -1150,6 +1150,7 @@ static struct sk_buff *qfq_dequeue(struc
 	if (!skb)
 		return NULL;
 
+	qdisc_qstats_backlog_dec(sch, skb);
 	sch->q.qlen--;
 	qdisc_bstats_update(sch, skb);
 
@@ -1250,6 +1251,7 @@ static int qfq_enqueue(struct sk_buff *s
 	}
 
 	bstats_update(&cl->bstats, skb);
+	qdisc_qstats_backlog_inc(sch, skb);
 	++sch->q.qlen;
 
 	agg = cl->agg;
@@ -1516,6 +1518,7 @@ static void qfq_reset_qdisc(struct Qdisc
 			qdisc_reset(cl->qdisc);
 		}
 	}
+	sch->qstats.backlog = 0;
 	sch->q.qlen = 0;
 }
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/sched/sch_sfb.c linux-libre-4.4.223-gnu/net/sched/sch_sfb.c
--- linux-libre-4.4.222-gnu/net/sched/sch_sfb.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/sched/sch_sfb.c	2020-05-10 04:26:37.000000000 -0400
@@ -400,6 +400,7 @@ static int sfb_enqueue(struct sk_buff *s
 enqueue:
 	ret = qdisc_enqueue(skb, child);
 	if (likely(ret == NET_XMIT_SUCCESS)) {
+		qdisc_qstats_backlog_inc(sch, skb);
 		sch->q.qlen++;
 		increment_qlen(skb, q);
 	} else if (net_xmit_drop_count(ret)) {
@@ -428,6 +429,7 @@ static struct sk_buff *sfb_dequeue(struc
 
 	if (skb) {
 		qdisc_bstats_update(sch, skb);
+		qdisc_qstats_backlog_dec(sch, skb);
 		sch->q.qlen--;
 		decrement_qlen(skb, q);
 	}
@@ -450,6 +452,7 @@ static void sfb_reset(struct Qdisc *sch)
 	struct sfb_sched_data *q = qdisc_priv(sch);
 
 	qdisc_reset(q->qdisc);
+	sch->qstats.backlog = 0;
 	sch->q.qlen = 0;
 	q->slot = 0;
 	q->double_buffering = false;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/sched/sch_tbf.c linux-libre-4.4.223-gnu/net/sched/sch_tbf.c
--- linux-libre-4.4.222-gnu/net/sched/sch_tbf.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/sched/sch_tbf.c	2020-05-10 04:26:37.000000000 -0400
@@ -197,6 +197,7 @@ static int tbf_enqueue(struct sk_buff *s
 		return ret;
 	}
 
+	qdisc_qstats_backlog_inc(sch, skb);
 	sch->q.qlen++;
 	return NET_XMIT_SUCCESS;
 }
@@ -207,6 +208,7 @@ static unsigned int tbf_drop(struct Qdis
 	unsigned int len = 0;
 
 	if (q->qdisc->ops->drop && (len = q->qdisc->ops->drop(q->qdisc)) != 0) {
+		sch->qstats.backlog -= len;
 		sch->q.qlen--;
 		qdisc_qstats_drop(sch);
 	}
@@ -253,6 +255,7 @@ static struct sk_buff *tbf_dequeue(struc
 			q->t_c = now;
 			q->tokens = toks;
 			q->ptokens = ptoks;
+			qdisc_qstats_backlog_dec(sch, skb);
 			sch->q.qlen--;
 			qdisc_unthrottled(sch);
 			qdisc_bstats_update(sch, skb);
@@ -284,6 +287,7 @@ static void tbf_reset(struct Qdisc *sch)
 	struct tbf_sched_data *q = qdisc_priv(sch);
 
 	qdisc_reset(q->qdisc);
+	sch->qstats.backlog = 0;
 	sch->q.qlen = 0;
 	q->t_c = ktime_get_ns();
 	q->tokens = q->buffer;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/sctp/associola.c linux-libre-4.4.223-gnu/net/sctp/associola.c
--- linux-libre-4.4.222-gnu/net/sctp/associola.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/sctp/associola.c	2020-05-10 04:26:37.000000000 -0400
@@ -1290,7 +1290,7 @@ static struct sctp_transport *sctp_trans
 	if (score_curr > score_best)
 		return curr;
 	else if (score_curr == score_best)
-		return sctp_trans_elect_tie(curr, best);
+		return sctp_trans_elect_tie(best, curr);
 	else
 		return best;
 }
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/sctp/sm_make_chunk.c linux-libre-4.4.223-gnu/net/sctp/sm_make_chunk.c
--- linux-libre-4.4.222-gnu/net/sctp/sm_make_chunk.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/sctp/sm_make_chunk.c	2020-05-10 04:26:37.000000000 -0400
@@ -857,7 +857,11 @@ struct sctp_chunk *sctp_make_shutdown(co
 	sctp_shutdownhdr_t shut;
 	__u32 ctsn;
 
-	ctsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map);
+	if (chunk && chunk->asoc)
+		ctsn = sctp_tsnmap_get_ctsn(&chunk->asoc->peer.tsn_map);
+	else
+		ctsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map);
+
 	shut.cum_tsn_ack = htonl(ctsn);
 
 	retval = sctp_make_control(asoc, SCTP_CID_SHUTDOWN, 0,
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/sctp/transport.c linux-libre-4.4.223-gnu/net/sctp/transport.c
--- linux-libre-4.4.222-gnu/net/sctp/transport.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/sctp/transport.c	2020-05-10 04:26:37.000000000 -0400
@@ -72,7 +72,7 @@ static struct sctp_transport *sctp_trans
 	 */
 	peer->rto = msecs_to_jiffies(net->sctp.rto_initial);
 
-	peer->last_time_heard = ktime_get();
+	peer->last_time_heard = ktime_set(0, 0);
 	peer->last_time_ecne_reduced = jiffies;
 
 	peer->param_flags = SPP_HB_DISABLE |
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/sunrpc/xprtrdma/backchannel.c linux-libre-4.4.223-gnu/net/sunrpc/xprtrdma/backchannel.c
--- linux-libre-4.4.222-gnu/net/sunrpc/xprtrdma/backchannel.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/sunrpc/xprtrdma/backchannel.c	2020-05-10 04:26:37.000000000 -0400
@@ -42,8 +42,8 @@ static int rpcrdma_bc_setup_rqst(struct
 	size_t size;
 
 	req = rpcrdma_create_req(r_xprt);
-	if (!req)
-		return -ENOMEM;
+	if (IS_ERR(req))
+		return PTR_ERR(req);
 	req->rl_backchannel = true;
 
 	size = RPCRDMA_INLINE_WRITE_THRESHOLD(rqst);
@@ -84,25 +84,13 @@ out_fail:
 static int rpcrdma_bc_setup_reps(struct rpcrdma_xprt *r_xprt,
 				 unsigned int count)
 {
-	struct rpcrdma_buffer *buffers = &r_xprt->rx_buf;
-	struct rpcrdma_rep *rep;
-	unsigned long flags;
 	int rc = 0;
 
 	while (count--) {
-		rep = rpcrdma_create_rep(r_xprt);
-		if (IS_ERR(rep)) {
-			pr_err("RPC:       %s: reply buffer alloc failed\n",
-			       __func__);
-			rc = PTR_ERR(rep);
+		rc = rpcrdma_create_rep(r_xprt);
+		if (rc)
 			break;
-		}
-
-		spin_lock_irqsave(&buffers->rb_lock, flags);
-		list_add(&rep->rr_list, &buffers->rb_recv_bufs);
-		spin_unlock_irqrestore(&buffers->rb_lock, flags);
 	}
-
 	return rc;
 }
 
@@ -341,6 +329,8 @@ void rpcrdma_bc_receive_call(struct rpcr
 	rqst->rq_reply_bytes_recvd = 0;
 	rqst->rq_bytes_sent = 0;
 	rqst->rq_xid = headerp->rm_xid;
+
+	rqst->rq_private_buf.len = size;
 	set_bit(RPC_BC_PA_IN_USE, &rqst->rq_bc_pa_state);
 
 	buf = &rqst->rq_rcv_buf;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/sunrpc/xprtrdma/transport.c linux-libre-4.4.223-gnu/net/sunrpc/xprtrdma/transport.c
--- linux-libre-4.4.222-gnu/net/sunrpc/xprtrdma/transport.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/sunrpc/xprtrdma/transport.c	2020-05-10 04:26:37.000000000 -0400
@@ -576,6 +576,9 @@ xprt_rdma_free(void *buffer)
 
 	rb = container_of(buffer, struct rpcrdma_regbuf, rg_base[0]);
 	req = rb->rg_owner;
+	if (req->rl_backchannel)
+		return;
+
 	r_xprt = container_of(req->rl_buffer, struct rpcrdma_xprt, rx_buf);
 
 	dprintk("RPC:       %s: called on 0x%p\n", __func__, req->rl_reply);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/sunrpc/xprtrdma/verbs.c linux-libre-4.4.223-gnu/net/sunrpc/xprtrdma/verbs.c
--- linux-libre-4.4.222-gnu/net/sunrpc/xprtrdma/verbs.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/sunrpc/xprtrdma/verbs.c	2020-05-10 04:26:37.000000000 -0400
@@ -911,10 +911,17 @@ rpcrdma_create_req(struct rpcrdma_xprt *
 	return req;
 }
 
-struct rpcrdma_rep *
-rpcrdma_create_rep(struct rpcrdma_xprt *r_xprt)
+/**
+ * rpcrdma_create_rep - Allocate an rpcrdma_rep object
+ * @r_xprt: controlling transport
+ *
+ * Returns 0 on success or a negative errno on failure.
+ */
+int
+ rpcrdma_create_rep(struct rpcrdma_xprt *r_xprt)
 {
 	struct rpcrdma_create_data_internal *cdata = &r_xprt->rx_data;
+	struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
 	struct rpcrdma_ia *ia = &r_xprt->rx_ia;
 	struct rpcrdma_rep *rep;
 	int rc;
@@ -934,12 +941,18 @@ rpcrdma_create_rep(struct rpcrdma_xprt *
 	rep->rr_device = ia->ri_device;
 	rep->rr_rxprt = r_xprt;
 	INIT_WORK(&rep->rr_work, rpcrdma_receive_worker);
-	return rep;
+
+	spin_lock(&buf->rb_lock);
+	list_add(&rep->rr_list, &buf->rb_recv_bufs);
+	spin_unlock(&buf->rb_lock);
+	return 0;
 
 out_free:
 	kfree(rep);
 out:
-	return ERR_PTR(rc);
+	dprintk("RPC:       %s: reply buffer %d alloc failed\n",
+		__func__, rc);
+	return rc;
 }
 
 int
@@ -975,17 +988,10 @@ rpcrdma_buffer_create(struct rpcrdma_xpr
 	}
 
 	INIT_LIST_HEAD(&buf->rb_recv_bufs);
-	for (i = 0; i < buf->rb_max_requests + 2; i++) {
-		struct rpcrdma_rep *rep;
-
-		rep = rpcrdma_create_rep(r_xprt);
-		if (IS_ERR(rep)) {
-			dprintk("RPC:       %s: reply buffer %d alloc failed\n",
-				__func__, i);
-			rc = PTR_ERR(rep);
+	for (i = 0; i <= buf->rb_max_requests; i++) {
+		rc = rpcrdma_create_rep(r_xprt);
+		if (rc)
 			goto out;
-		}
-		list_add(&rep->rr_list, &buf->rb_recv_bufs);
 	}
 
 	return 0;
@@ -1337,15 +1343,14 @@ rpcrdma_ep_post_extra_recv(struct rpcrdm
 	struct rpcrdma_ia *ia = &r_xprt->rx_ia;
 	struct rpcrdma_ep *ep = &r_xprt->rx_ep;
 	struct rpcrdma_rep *rep;
-	unsigned long flags;
 	int rc;
 
 	while (count--) {
-		spin_lock_irqsave(&buffers->rb_lock, flags);
+		spin_lock(&buffers->rb_lock);
 		if (list_empty(&buffers->rb_recv_bufs))
 			goto out_reqbuf;
 		rep = rpcrdma_buffer_get_rep_locked(buffers);
-		spin_unlock_irqrestore(&buffers->rb_lock, flags);
+		spin_unlock(&buffers->rb_lock);
 
 		rc = rpcrdma_ep_post_recv(ia, ep, rep);
 		if (rc)
@@ -1355,7 +1360,7 @@ rpcrdma_ep_post_extra_recv(struct rpcrdm
 	return 0;
 
 out_reqbuf:
-	spin_unlock_irqrestore(&buffers->rb_lock, flags);
+	spin_unlock(&buffers->rb_lock);
 	pr_warn("%s: no extra receive buffers\n", __func__);
 	return -ENOMEM;
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/sunrpc/xprtrdma/xprt_rdma.h linux-libre-4.4.223-gnu/net/sunrpc/xprtrdma/xprt_rdma.h
--- linux-libre-4.4.222-gnu/net/sunrpc/xprtrdma/xprt_rdma.h	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/sunrpc/xprtrdma/xprt_rdma.h	2020-05-10 04:26:37.000000000 -0400
@@ -431,8 +431,8 @@ int rpcrdma_ep_post_recv(struct rpcrdma_
  * Buffer calls - xprtrdma/verbs.c
  */
 struct rpcrdma_req *rpcrdma_create_req(struct rpcrdma_xprt *);
-struct rpcrdma_rep *rpcrdma_create_rep(struct rpcrdma_xprt *);
 void rpcrdma_destroy_req(struct rpcrdma_ia *, struct rpcrdma_req *);
+int rpcrdma_create_rep(struct rpcrdma_xprt *r_xprt);
 int rpcrdma_buffer_create(struct rpcrdma_xprt *);
 void rpcrdma_buffer_destroy(struct rpcrdma_buffer *);
 
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/tipc/udp_media.c linux-libre-4.4.223-gnu/net/tipc/udp_media.c
--- linux-libre-4.4.222-gnu/net/tipc/udp_media.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/tipc/udp_media.c	2020-05-10 04:26:37.000000000 -0400
@@ -405,10 +405,13 @@ static int tipc_udp_enable(struct net *n
 	tuncfg.encap_destroy = NULL;
 	setup_udp_tunnel_sock(net, ub->ubsock, &tuncfg);
 
-	if (enable_mcast(ub, remote))
+	err = enable_mcast(ub, remote);
+	if (err)
 		goto err;
 	return 0;
 err:
+	if (ub->ubsock)
+		udp_tunnel_sock_release(ub->ubsock);
 	kfree(ub);
 	return err;
 }
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/xfrm/xfrm_input.c linux-libre-4.4.223-gnu/net/xfrm/xfrm_input.c
--- linux-libre-4.4.222-gnu/net/xfrm/xfrm_input.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/xfrm/xfrm_input.c	2020-05-10 04:26:37.000000000 -0400
@@ -207,15 +207,15 @@ int xfrm_input(struct sk_buff *skb, int
 	family = XFRM_SPI_SKB_CB(skb)->family;
 
 	/* if tunnel is present override skb->mark value with tunnel i_key */
-	if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4) {
-		switch (family) {
-		case AF_INET:
+	switch (family) {
+	case AF_INET:
+		if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4)
 			mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4->parms.i_key);
-			break;
-		case AF_INET6:
+		break;
+	case AF_INET6:
+		if (XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6)
 			mark = be32_to_cpu(XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip6->parms.i_key);
-			break;
-		}
+		break;
 	}
 
 	/* Allocate new secpath or COW existing one. */
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/xfrm/xfrm_state.c linux-libre-4.4.223-gnu/net/xfrm/xfrm_state.c
--- linux-libre-4.4.222-gnu/net/xfrm/xfrm_state.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/xfrm/xfrm_state.c	2020-05-10 04:26:37.000000000 -0400
@@ -332,6 +332,7 @@ static void xfrm_state_gc_destroy(struct
 {
 	tasklet_hrtimer_cancel(&x->mtimer);
 	del_timer_sync(&x->rtimer);
+	kfree(x->aead);
 	kfree(x->aalg);
 	kfree(x->ealg);
 	kfree(x->calg);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/net/xfrm/xfrm_user.c linux-libre-4.4.223-gnu/net/xfrm/xfrm_user.c
--- linux-libre-4.4.222-gnu/net/xfrm/xfrm_user.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/net/xfrm/xfrm_user.c	2020-05-10 04:26:37.000000000 -0400
@@ -609,9 +609,12 @@ static struct xfrm_state *xfrm_state_con
 	if (err)
 		goto error;
 
-	if (attrs[XFRMA_SEC_CTX] &&
-	    security_xfrm_state_alloc(x, nla_data(attrs[XFRMA_SEC_CTX])))
-		goto error;
+	if (attrs[XFRMA_SEC_CTX]) {
+		err = security_xfrm_state_alloc(x,
+						nla_data(attrs[XFRMA_SEC_CTX]));
+		if (err)
+			goto error;
+	}
 
 	if ((err = xfrm_alloc_replay_state_esn(&x->replay_esn, &x->preplay_esn,
 					       attrs[XFRMA_REPLAY_ESN_VAL])))
@@ -923,7 +926,8 @@ static int xfrm_dump_sa_done(struct netl
 	struct sock *sk = cb->skb->sk;
 	struct net *net = sock_net(sk);
 
-	xfrm_state_walk_done(walk, net);
+	if (cb->args[0])
+		xfrm_state_walk_done(walk, net);
 	return 0;
 }
 
@@ -948,8 +952,6 @@ static int xfrm_dump_sa(struct sk_buff *
 		u8 proto = 0;
 		int err;
 
-		cb->args[0] = 1;
-
 		err = nlmsg_parse(cb->nlh, 0, attrs, XFRMA_MAX,
 				  xfrma_policy);
 		if (err < 0)
@@ -966,6 +968,7 @@ static int xfrm_dump_sa(struct sk_buff *
 			proto = nla_get_u8(attrs[XFRMA_PROTO]);
 
 		xfrm_state_walk_init(walk, proto, filter);
+		cb->args[0] = 1;
 	}
 
 	(void) xfrm_state_walk(net, walk, dump_one_state, &info);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/scripts/config linux-libre-4.4.223-gnu/scripts/config
--- linux-libre-4.4.222-gnu/scripts/config	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/scripts/config	2020-05-10 04:26:37.000000000 -0400
@@ -6,6 +6,9 @@ myname=${0##*/}
 # If no prefix forced, use the default CONFIG_
 CONFIG_="${CONFIG_-CONFIG_}"
 
+# We use an uncommon delimiter for sed substitutions
+SED_DELIM=$(echo -en "\001")
+
 usage() {
 	cat >&2 <<EOL
 Manipulate options in a .config file from the command line.
@@ -82,7 +85,7 @@ txt_subst() {
 	local infile="$3"
 	local tmpfile="$infile.swp"
 
-	sed -e "s:$before:$after:" "$infile" >"$tmpfile"
+	sed -e "s$SED_DELIM$before$SED_DELIM$after$SED_DELIM" "$infile" >"$tmpfile"
 	# replace original file with the edited one
 	mv "$tmpfile" "$infile"
 }
diff -druNp --no-dereference linux-libre-4.4.222-gnu/sound/pci/fm801.c linux-libre-4.4.223-gnu/sound/pci/fm801.c
--- linux-libre-4.4.222-gnu/sound/pci/fm801.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/sound/pci/fm801.c	2020-05-10 04:26:37.000000000 -0400
@@ -1088,26 +1088,20 @@ static int wait_for_codec(struct fm801 *
 	return -EIO;
 }
 
-static int snd_fm801_chip_init(struct fm801 *chip, int resume)
+static int reset_codec(struct fm801 *chip)
 {
-	unsigned short cmdw;
-
-	if (chip->tea575x_tuner & TUNER_ONLY)
-		goto __ac97_ok;
-
 	/* codec cold reset + AC'97 warm reset */
 	fm801_writew(chip, CODEC_CTRL, (1 << 5) | (1 << 6));
 	fm801_readw(chip, CODEC_CTRL); /* flush posting data */
 	udelay(100);
 	fm801_writew(chip, CODEC_CTRL, 0);
 
-	if (wait_for_codec(chip, 0, AC97_RESET, msecs_to_jiffies(750)) < 0)
-		if (!resume) {
-			dev_info(chip->card->dev,
-				 "Primary AC'97 codec not found, assume SF64-PCR (tuner-only)\n");
-			chip->tea575x_tuner = 3 | TUNER_ONLY;
-			goto __ac97_ok;
-		}
+	return wait_for_codec(chip, 0, AC97_RESET, msecs_to_jiffies(750));
+}
+
+static void snd_fm801_chip_multichannel_init(struct fm801 *chip)
+{
+	unsigned short cmdw;
 
 	if (chip->multichannel) {
 		if (chip->secondary_addr) {
@@ -1134,8 +1128,11 @@ static int snd_fm801_chip_init(struct fm
 		/* cause timeout problems */
 		wait_for_codec(chip, 0, AC97_VENDOR_ID1, msecs_to_jiffies(750));
 	}
+}
 
-      __ac97_ok:
+static void snd_fm801_chip_init(struct fm801 *chip)
+{
+	unsigned short cmdw;
 
 	/* init volume */
 	fm801_writew(chip, PCM_VOL, 0x0808);
@@ -1156,11 +1153,8 @@ static int snd_fm801_chip_init(struct fm
 	/* interrupt clear */
 	fm801_writew(chip, IRQ_STATUS,
 		     FM801_IRQ_PLAYBACK | FM801_IRQ_CAPTURE | FM801_IRQ_MPU);
-
-	return 0;
 }
 
-
 static int snd_fm801_free(struct fm801 *chip)
 {
 	unsigned short cmdw;
@@ -1173,6 +1167,8 @@ static int snd_fm801_free(struct fm801 *
 	cmdw |= 0x00c3;
 	fm801_writew(chip, IRQ_MASK, cmdw);
 
+	devm_free_irq(&chip->pci->dev, chip->irq, chip);
+
       __end_hw:
 #ifdef CONFIG_SND_FM801_TEA575X_BOOL
 	if (!(chip->tea575x_tuner & TUNER_DISABLED)) {
@@ -1215,7 +1211,21 @@ static int snd_fm801_create(struct snd_c
 	if ((err = pci_request_regions(pci, "FM801")) < 0)
 		return err;
 	chip->port = pci_resource_start(pci, 0);
-	if ((tea575x_tuner & TUNER_ONLY) == 0) {
+
+	if (pci->revision >= 0xb1)	/* FM801-AU */
+		chip->multichannel = 1;
+
+	if (!(chip->tea575x_tuner & TUNER_ONLY)) {
+		if (reset_codec(chip) < 0) {
+			dev_info(chip->card->dev,
+				 "Primary AC'97 codec not found, assume SF64-PCR (tuner-only)\n");
+			chip->tea575x_tuner = 3 | TUNER_ONLY;
+		} else {
+			snd_fm801_chip_multichannel_init(chip);
+		}
+	}
+
+	if ((chip->tea575x_tuner & TUNER_ONLY) == 0) {
 		if (devm_request_irq(&pci->dev, pci->irq, snd_fm801_interrupt,
 				IRQF_SHARED, KBUILD_MODNAME, chip)) {
 			dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq);
@@ -1226,12 +1236,7 @@ static int snd_fm801_create(struct snd_c
 		pci_set_master(pci);
 	}
 
-	if (pci->revision >= 0xb1)	/* FM801-AU */
-		chip->multichannel = 1;
-
-	snd_fm801_chip_init(chip, 0);
-	/* init might set tuner access method */
-	tea575x_tuner = chip->tea575x_tuner;
+	snd_fm801_chip_init(chip);
 
 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
 		snd_fm801_free(chip);
@@ -1249,14 +1254,16 @@ static int snd_fm801_create(struct snd_c
 	chip->tea.private_data = chip;
 	chip->tea.ops = &snd_fm801_tea_ops;
 	sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci));
-	if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 &&
-	    (tea575x_tuner & TUNER_TYPE_MASK) < 4) {
+	if ((chip->tea575x_tuner & TUNER_TYPE_MASK) > 0 &&
+	    (chip->tea575x_tuner & TUNER_TYPE_MASK) < 4) {
 		if (snd_tea575x_init(&chip->tea, THIS_MODULE)) {
 			dev_err(card->dev, "TEA575x radio not found\n");
 			snd_fm801_free(chip);
 			return -ENODEV;
 		}
-	} else if ((tea575x_tuner & TUNER_TYPE_MASK) == 0) {
+	} else if ((chip->tea575x_tuner & TUNER_TYPE_MASK) == 0) {
+		unsigned int tuner_only = chip->tea575x_tuner & TUNER_ONLY;
+
 		/* autodetect tuner connection */
 		for (tea575x_tuner = 1; tea575x_tuner <= 3; tea575x_tuner++) {
 			chip->tea575x_tuner = tea575x_tuner;
@@ -1271,6 +1278,8 @@ static int snd_fm801_create(struct snd_c
 			dev_err(card->dev, "TEA575x radio not found\n");
 			chip->tea575x_tuner = TUNER_DISABLED;
 		}
+
+		chip->tea575x_tuner |= tuner_only;
 	}
 	if (!(chip->tea575x_tuner & TUNER_DISABLED)) {
 		strlcpy(chip->tea.card, get_tea575x_gpio(chip)->name,
@@ -1389,7 +1398,13 @@ static int snd_fm801_resume(struct devic
 	struct fm801 *chip = card->private_data;
 	int i;
 
-	snd_fm801_chip_init(chip, 1);
+	if (chip->tea575x_tuner & TUNER_ONLY) {
+		snd_fm801_chip_init(chip);
+	} else {
+		reset_codec(chip);
+		snd_fm801_chip_multichannel_init(chip);
+		snd_fm801_chip_init(chip);
+	}
 	snd_ac97_resume(chip->ac97);
 	snd_ac97_resume(chip->ac97_sec);
 	for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
diff -druNp --no-dereference linux-libre-4.4.222-gnu/sound/pci/hda/hda_intel.c linux-libre-4.4.223-gnu/sound/pci/hda/hda_intel.c
--- linux-libre-4.4.222-gnu/sound/pci/hda/hda_intel.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/sound/pci/hda/hda_intel.c	2020-05-10 04:26:37.000000000 -0400
@@ -1977,9 +1977,10 @@ static const struct hdac_io_ops pci_hda_
  * some HD-audio PCI entries are exposed without any codecs, and such devices
  * should be ignored from the beginning.
  */
-static const struct snd_pci_quirk driver_blacklist[] = {
-	SND_PCI_QUIRK(0x1462, 0xcb59, "MSI TRX40 Creator", 0),
-	SND_PCI_QUIRK(0x1462, 0xcb60, "MSI TRX40", 0),
+static const struct pci_device_id driver_blacklist[] = {
+	{ PCI_DEVICE_SUB(0x1022, 0x1487, 0x1043, 0x874f) }, /* ASUS ROG Zenith II / Strix */
+	{ PCI_DEVICE_SUB(0x1022, 0x1487, 0x1462, 0xcb59) }, /* MSI TRX40 Creator */
+	{ PCI_DEVICE_SUB(0x1022, 0x1487, 0x1462, 0xcb60) }, /* MSI TRX40 */
 	{}
 };
 
@@ -2002,7 +2003,7 @@ static int azx_probe(struct pci_dev *pci
 	bool schedule_probe;
 	int err;
 
-	if (snd_pci_quirk_lookup(pci, driver_blacklist)) {
+	if (pci_match_id(driver_blacklist, pci)) {
 		dev_info(&pci->dev, "Skipping the blacklisted device\n");
 		return -ENODEV;
 	}
diff -druNp --no-dereference linux-libre-4.4.222-gnu/sound/soc/fsl/fsl_ssi.c linux-libre-4.4.223-gnu/sound/soc/fsl/fsl_ssi.c
--- linux-libre-4.4.222-gnu/sound/soc/fsl/fsl_ssi.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/sound/soc/fsl/fsl_ssi.c	2020-05-10 04:26:37.000000000 -0400
@@ -146,6 +146,7 @@ static bool fsl_ssi_volatile_reg(struct
 	case CCSR_SSI_SRX1:
 	case CCSR_SSI_SISR:
 	case CCSR_SSI_SFCSR:
+	case CCSR_SSI_SACNT:
 	case CCSR_SSI_SACADD:
 	case CCSR_SSI_SACDAT:
 	case CCSR_SSI_SATAG:
@@ -239,8 +240,9 @@ struct fsl_ssi_private {
 	unsigned int baudclk_streams;
 	unsigned int bitclk_freq;
 
-	/*regcache for SFCSR*/
+	/* regcache for volatile regs */
 	u32 regcache_sfcsr;
+	u32 regcache_sacnt;
 
 	/* DMA params */
 	struct snd_dmaengine_dai_dma_data dma_params_tx;
@@ -1597,6 +1599,8 @@ static int fsl_ssi_suspend(struct device
 
 	regmap_read(regs, CCSR_SSI_SFCSR,
 			&ssi_private->regcache_sfcsr);
+	regmap_read(regs, CCSR_SSI_SACNT,
+			&ssi_private->regcache_sacnt);
 
 	regcache_cache_only(regs, true);
 	regcache_mark_dirty(regs);
@@ -1615,6 +1619,8 @@ static int fsl_ssi_resume(struct device
 			CCSR_SSI_SFCSR_RFWM1_MASK | CCSR_SSI_SFCSR_TFWM1_MASK |
 			CCSR_SSI_SFCSR_RFWM0_MASK | CCSR_SSI_SFCSR_TFWM0_MASK,
 			ssi_private->regcache_sfcsr);
+	regmap_write(regs, CCSR_SSI_SACNT,
+			ssi_private->regcache_sacnt);
 
 	return regcache_sync(regs);
 }
diff -druNp --no-dereference linux-libre-4.4.222-gnu/sound/soc/intel/atom/sst/sst_stream.c linux-libre-4.4.223-gnu/sound/soc/intel/atom/sst/sst_stream.c
--- linux-libre-4.4.222-gnu/sound/soc/intel/atom/sst/sst_stream.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/sound/soc/intel/atom/sst/sst_stream.c	2020-05-10 04:26:37.000000000 -0400
@@ -108,7 +108,7 @@ int sst_alloc_stream_mrfld(struct intel_
 			str_id, pipe_id);
 	ret = sst_prepare_and_post_msg(sst_drv_ctx, task_id, IPC_CMD,
 			IPC_IA_ALLOC_STREAM_MRFLD, pipe_id, sizeof(alloc_param),
-			&alloc_param, data, true, true, false, true);
+			&alloc_param, &data, true, true, false, true);
 
 	if (ret < 0) {
 		dev_err(sst_drv_ctx->dev, "FW alloc failed ret %d\n", ret);
diff -druNp --no-dereference linux-libre-4.4.222-gnu/sound/soc/tegra/tegra_alc5632.c linux-libre-4.4.223-gnu/sound/soc/tegra/tegra_alc5632.c
--- linux-libre-4.4.222-gnu/sound/soc/tegra/tegra_alc5632.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/sound/soc/tegra/tegra_alc5632.c	2020-05-10 04:26:37.000000000 -0400
@@ -101,12 +101,16 @@ static const struct snd_kcontrol_new teg
 
 static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
 {
+	int ret;
 	struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(rtd->card);
 
-	snd_soc_card_jack_new(rtd->card, "Headset Jack", SND_JACK_HEADSET,
-			      &tegra_alc5632_hs_jack,
-			      tegra_alc5632_hs_jack_pins,
-			      ARRAY_SIZE(tegra_alc5632_hs_jack_pins));
+	ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
+				    SND_JACK_HEADSET,
+				    &tegra_alc5632_hs_jack,
+				    tegra_alc5632_hs_jack_pins,
+				    ARRAY_SIZE(tegra_alc5632_hs_jack_pins));
+	if (ret)
+		return ret;
 
 	if (gpio_is_valid(machine->gpio_hp_det)) {
 		tegra_alc5632_hp_jack_gpio.gpio = machine->gpio_hp_det;
diff -druNp --no-dereference linux-libre-4.4.222-gnu/tools/perf/util/perf_regs.c linux-libre-4.4.223-gnu/tools/perf/util/perf_regs.c
--- linux-libre-4.4.222-gnu/tools/perf/util/perf_regs.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/tools/perf/util/perf_regs.c	2020-05-10 04:26:37.000000000 -0400
@@ -12,18 +12,18 @@ int perf_reg_value(u64 *valp, struct reg
 	int i, idx = 0;
 	u64 mask = regs->mask;
 
-	if (regs->cache_mask & (1 << id))
+	if (regs->cache_mask & (1ULL << id))
 		goto out;
 
-	if (!(mask & (1 << id)))
+	if (!(mask & (1ULL << id)))
 		return -EINVAL;
 
 	for (i = 0; i < id; i++) {
-		if (mask & (1 << i))
+		if (mask & (1ULL << i))
 			idx++;
 	}
 
-	regs->cache_mask |= (1 << id);
+	regs->cache_mask |= (1ULL << id);
 	regs->cache_regs[id] = regs->regs[idx];
 
 out:
diff -druNp --no-dereference linux-libre-4.4.222-gnu/tools/testing/selftests/ipc/msgque.c linux-libre-4.4.223-gnu/tools/testing/selftests/ipc/msgque.c
--- linux-libre-4.4.222-gnu/tools/testing/selftests/ipc/msgque.c	2020-05-05 13:13:25.000000000 -0400
+++ linux-libre-4.4.223-gnu/tools/testing/selftests/ipc/msgque.c	2020-05-10 04:26:37.000000000 -0400
@@ -135,7 +135,7 @@ int dump_queue(struct msgque_data *msgqu
 	for (kern_id = 0; kern_id < 256; kern_id++) {
 		ret = msgctl(kern_id, MSG_STAT, &ds);
 		if (ret < 0) {
-			if (errno == -EINVAL)
+			if (errno == EINVAL)
 				continue;
 			printf("Failed to get stats for IPC queue with id %d\n",
 					kern_id);
