commit:     9e6cc3524305d869d5dcc420766da90c7031dd47
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Wed Mar 16 13:31:02 2022 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Wed Mar 16 13:31:02 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=9e6cc352

Linux patch 5.4.185

Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>

 0000_README              |    4 +
 1184_linux-5.4.185.patch | 1364 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1368 insertions(+)

diff --git a/0000_README b/0000_README
index fd6eed23..65389f5e 100644
--- a/0000_README
+++ b/0000_README
@@ -779,6 +779,10 @@ Patch:  1183_linux-5.4.184.patch
 From:   http://www.kernel.org
 Desc:   Linux 5.4.184
 
+Patch:  1184_linux-5.4.185.patch
+From:   http://www.kernel.org
+Desc:   Linux 5.4.185
+
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
 Desc:   Support for namespace user.pax.* on tmpfs.

diff --git a/1184_linux-5.4.185.patch b/1184_linux-5.4.185.patch
new file mode 100644
index 00000000..ee7901f9
--- /dev/null
+++ b/1184_linux-5.4.185.patch
@@ -0,0 +1,1364 @@
+diff --git a/Makefile b/Makefile
+index e914e1a8a7d2c..bd3bdf86b992e 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 5
+ PATCHLEVEL = 4
+-SUBLEVEL = 184
++SUBLEVEL = 185
+ EXTRAVERSION =
+ NAME = Kleptomaniac Octopus
+ 
+diff --git a/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi 
b/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi
+index 996e006e06c25..f310f4d3bcc7c 100644
+--- a/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi
++++ b/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi
+@@ -118,7 +118,7 @@
+       };
+ 
+       pinctrl_fwqspid_default: fwqspid_default {
+-              function = "FWQSPID";
++              function = "FWSPID";
+               groups = "FWQSPID";
+       };
+ 
+diff --git a/arch/arm/include/asm/spectre.h b/arch/arm/include/asm/spectre.h
+index d1fa5607d3aa3..85f9e538fb325 100644
+--- a/arch/arm/include/asm/spectre.h
++++ b/arch/arm/include/asm/spectre.h
+@@ -25,7 +25,13 @@ enum {
+       SPECTRE_V2_METHOD_LOOP8 = BIT(__SPECTRE_V2_METHOD_LOOP8),
+ };
+ 
++#ifdef CONFIG_GENERIC_CPU_VULNERABILITIES
+ void spectre_v2_update_state(unsigned int state, unsigned int methods);
++#else
++static inline void spectre_v2_update_state(unsigned int state,
++                                         unsigned int methods)
++{}
++#endif
+ 
+ int spectre_bhb_update_vectors(unsigned int method);
+ 
+diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
+index 94d25425b7bce..3d65fa56a0e5d 100644
+--- a/arch/arm/kernel/entry-armv.S
++++ b/arch/arm/kernel/entry-armv.S
+@@ -1043,9 +1043,9 @@ vector_bhb_loop8_\name:
+ 
+       @ bhb workaround
+       mov     r0, #8
+-1:    b       . + 4
++3:    b       . + 4
+       subs    r0, r0, #1
+-      bne     1b
++      bne     3b
+       dsb
+       isb
+       b       2b
+diff --git a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts 
b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
+index 16e73597bb78c..2e8239d489f82 100644
+--- a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
++++ b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
+@@ -18,6 +18,7 @@
+ 
+       aliases {
+               spi0 = &spi0;
++              ethernet0 = &eth0;
+               ethernet1 = &eth1;
+       };
+ 
+@@ -137,7 +138,9 @@
+       /*
+        * U-Boot port for Turris Mox has a bug which always expects that 
"ranges" DT property
+        * contains exactly 2 ranges with 3 (child) address cells, 2 (parent) 
address cells and
+-       * 2 size cells and also expects that the second range starts at 16 MB 
offset. If these
++       * 2 size cells and also expects that the second range starts at 16 MB 
offset. Also it
++       * expects that first range uses same address for PCI (child) and CPU 
(parent) cells (so
++       * no remapping) and that this address is the lowest from all specified 
ranges. If these
+        * conditions are not met then U-Boot crashes during loading kernel DTB 
file. PCIe address
+        * space is 128 MB long, so the best split between MEM and IO is to use 
fixed 16 MB window
+        * for IO and the rest 112 MB (64+32+16) for MEM, despite that maximal 
IO size is just 64 kB.
+@@ -146,6 +149,9 @@
+        * 
https://source.denx.de/u-boot/u-boot/-/commit/cb2ddb291ee6fcbddd6d8f4ff49089dfe580f5d7
+        * 
https://source.denx.de/u-boot/u-boot/-/commit/c64ac3b3185aeb3846297ad7391fc6df8ecd73bf
+        * 
https://source.denx.de/u-boot/u-boot/-/commit/4a82fca8e330157081fc132a591ebd99ba02ee33
++       * Bug related to requirement of same child and parent addresses for 
first range is fixed
++       * in U-Boot version 2022.04 by following commit:
++       * 
https://source.denx.de/u-boot/u-boot/-/commit/1fd54253bca7d43d046bba4853fe5fafd034bc17
+        */
+       #address-cells = <3>;
+       #size-cells = <2>;
+diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi 
b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+index 3d15e4ab3f53a..9405d9c619ca6 100644
+--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
++++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+@@ -495,7 +495,7 @@
+                        * (totaling 127 MiB) for MEM.
+                        */
+                       ranges = <0x82000000 0 0xe8000000   0 0xe8000000   0 
0x07f00000   /* Port 0 MEM */
+-                                0x81000000 0 0xefff0000   0 0xefff0000   0 
0x00010000>; /* Port 0 IO */
++                                0x81000000 0 0x00000000   0 0xefff0000   0 
0x00010000>; /* Port 0 IO */
+                       interrupt-map-mask = <0 0 0 7>;
+                       interrupt-map = <0 0 0 1 &pcie_intc 0>,
+                                       <0 0 0 2 &pcie_intc 1>,
+diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c
+index 6bf5b16743843..a963b761e1a39 100644
+--- a/arch/riscv/kernel/module.c
++++ b/arch/riscv/kernel/module.c
+@@ -13,6 +13,19 @@
+ #include <asm/pgtable.h>
+ #include <asm/sections.h>
+ 
++/*
++ * The auipc+jalr instruction pair can reach any PC-relative offset
++ * in the range [-2^31 - 2^11, 2^31 - 2^11)
++ */
++static bool riscv_insn_valid_32bit_offset(ptrdiff_t val)
++{
++#ifdef CONFIG_32BIT
++      return true;
++#else
++      return (-(1L << 31) - (1L << 11)) <= val && val < ((1L << 31) - (1L << 
11));
++#endif
++}
++
+ static int apply_r_riscv_32_rela(struct module *me, u32 *location, Elf_Addr v)
+ {
+       if (v != (u32)v) {
+@@ -95,7 +108,7 @@ static int apply_r_riscv_pcrel_hi20_rela(struct module *me, 
u32 *location,
+       ptrdiff_t offset = (void *)v - (void *)location;
+       s32 hi20;
+ 
+-      if (offset != (s32)offset) {
++      if (!riscv_insn_valid_32bit_offset(offset)) {
+               pr_err(
+                 "%s: target %016llx can not be addressed by the 32-bit offset 
from PC = %p\n",
+                 me->name, (long long)v, location);
+@@ -197,10 +210,9 @@ static int apply_r_riscv_call_plt_rela(struct module *me, 
u32 *location,
+                                      Elf_Addr v)
+ {
+       ptrdiff_t offset = (void *)v - (void *)location;
+-      s32 fill_v = offset;
+       u32 hi20, lo12;
+ 
+-      if (offset != fill_v) {
++      if (!riscv_insn_valid_32bit_offset(offset)) {
+               /* Only emit the plt entry if offset over 32-bit range */
+               if (IS_ENABLED(CONFIG_MODULE_SECTIONS)) {
+                       offset = module_emit_plt_entry(me, v);
+@@ -224,10 +236,9 @@ static int apply_r_riscv_call_rela(struct module *me, u32 
*location,
+                                  Elf_Addr v)
+ {
+       ptrdiff_t offset = (void *)v - (void *)location;
+-      s32 fill_v = offset;
+       u32 hi20, lo12;
+ 
+-      if (offset != fill_v) {
++      if (!riscv_insn_valid_32bit_offset(offset)) {
+               pr_err(
+                 "%s: target %016llx can not be addressed by the 32-bit offset 
from PC = %p\n",
+                 me->name, (long long)v, location);
+diff --git a/arch/x86/include/asm/cpufeatures.h 
b/arch/x86/include/asm/cpufeatures.h
+index f48905f796e9d..56eb9a6524e96 100644
+--- a/arch/x86/include/asm/cpufeatures.h
++++ b/arch/x86/include/asm/cpufeatures.h
+@@ -96,6 +96,7 @@
+ #define X86_FEATURE_SYSCALL32         ( 3*32+14) /* "" syscall in IA32 
userspace */
+ #define X86_FEATURE_SYSENTER32                ( 3*32+15) /* "" sysenter in 
IA32 userspace */
+ #define X86_FEATURE_REP_GOOD          ( 3*32+16) /* REP microcode works well 
*/
++#define X86_FEATURE_SME_COHERENT      ( 3*32+17) /* "" AMD hardware-enforced 
cache coherency */
+ #define X86_FEATURE_LFENCE_RDTSC      ( 3*32+18) /* "" LFENCE synchronizes 
RDTSC */
+ #define X86_FEATURE_ACC_POWER         ( 3*32+19) /* AMD Accumulated Power 
Mechanism */
+ #define X86_FEATURE_NOPL              ( 3*32+20) /* The NOPL (0F 1F) 
instructions */
+@@ -107,6 +108,7 @@
+ #define X86_FEATURE_EXTD_APICID               ( 3*32+26) /* Extended APICID 
(8 bits) */
+ #define X86_FEATURE_AMD_DCM           ( 3*32+27) /* AMD multi-node processor 
*/
+ #define X86_FEATURE_APERFMPERF                ( 3*32+28) /* P-State hardware 
coordination feedback capability (APERF/MPERF MSRs) */
++/* free                                       ( 3*32+29) */
+ #define X86_FEATURE_NONSTOP_TSC_S3    ( 3*32+30) /* TSC doesn't stop in S3 
state */
+ #define X86_FEATURE_TSC_KNOWN_FREQ    ( 3*32+31) /* TSC has known frequency */
+ 
+diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c
+index adf9b71386eff..53004dbd55c47 100644
+--- a/arch/x86/kernel/cpu/scattered.c
++++ b/arch/x86/kernel/cpu/scattered.c
+@@ -41,6 +41,7 @@ static const struct cpuid_bit cpuid_bits[] = {
+       { X86_FEATURE_MBA,              CPUID_EBX,  6, 0x80000008, 0 },
+       { X86_FEATURE_SME,              CPUID_EAX,  0, 0x8000001f, 0 },
+       { X86_FEATURE_SEV,              CPUID_EAX,  1, 0x8000001f, 0 },
++      { X86_FEATURE_SME_COHERENT,     CPUID_EAX, 10, 0x8000001f, 0 },
+       { 0, 0, 0, 0, 0 }
+ };
+ 
+diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
+index 2f84509f28289..125970286f289 100644
+--- a/arch/x86/kvm/svm.c
++++ b/arch/x86/kvm/svm.c
+@@ -1904,7 +1904,8 @@ static void sev_clflush_pages(struct page *pages[], 
unsigned long npages)
+       uint8_t *page_virtual;
+       unsigned long i;
+ 
+-      if (npages == 0 || pages == NULL)
++      if (this_cpu_has(X86_FEATURE_SME_COHERENT) || npages == 0 ||
++          pages == NULL)
+               return;
+ 
+       for (i = 0; i < npages; i++) {
+diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
+index 281e584cfe39e..d61313f5c5b98 100644
+--- a/arch/x86/mm/pageattr.c
++++ b/arch/x86/mm/pageattr.c
+@@ -1967,7 +1967,7 @@ static int __set_memory_enc_dec(unsigned long addr, int 
numpages, bool enc)
+       /*
+        * Before changing the encryption attribute, we need to flush caches.
+        */
+-      cpa_flush(&cpa, 1);
++      cpa_flush(&cpa, !this_cpu_has(X86_FEATURE_SME_COHERENT));
+ 
+       ret = __change_page_attr_set_clr(&cpa, 1);
+ 
+diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
+index 816eb2db73080..4b3645e648ee9 100644
+--- a/drivers/block/virtio_blk.c
++++ b/drivers/block/virtio_blk.c
+@@ -980,9 +980,15 @@ static int virtblk_probe(struct virtio_device *vdev)
+ 
+               virtio_cread(vdev, struct virtio_blk_config, max_discard_seg,
+                            &v);
++
++              /*
++               * max_discard_seg == 0 is out of spec but we always
++               * handled it.
++               */
++              if (!v)
++                      v = sg_elems - 2;
+               blk_queue_max_discard_segments(q,
+-                                             min_not_zero(v,
+-                                                          
MAX_DISCARD_SEGMENTS));
++                                             min(v, MAX_DISCARD_SEGMENTS));
+ 
+               blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
+       }
+diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
+index a250f59708d85..888965bb93edf 100644
+--- a/drivers/clk/qcom/gdsc.c
++++ b/drivers/clk/qcom/gdsc.c
+@@ -1,6 +1,6 @@
+ // SPDX-License-Identifier: GPL-2.0-only
+ /*
+- * Copyright (c) 2015, 2017-2018, The Linux Foundation. All rights reserved.
++ * Copyright (c) 2015, 2017-2018, 2022, The Linux Foundation. All rights 
reserved.
+  */
+ 
+ #include <linux/bitops.h>
+@@ -31,9 +31,14 @@
+ #define CFG_GDSCR_OFFSET              0x4
+ 
+ /* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */
+-#define EN_REST_WAIT_VAL      (0x2 << 20)
+-#define EN_FEW_WAIT_VAL               (0x8 << 16)
+-#define CLK_DIS_WAIT_VAL      (0x2 << 12)
++#define EN_REST_WAIT_VAL      0x2
++#define EN_FEW_WAIT_VAL               0x8
++#define CLK_DIS_WAIT_VAL      0x2
++
++/* Transition delay shifts */
++#define EN_REST_WAIT_SHIFT    20
++#define EN_FEW_WAIT_SHIFT     16
++#define CLK_DIS_WAIT_SHIFT    12
+ 
+ #define RETAIN_MEM            BIT(14)
+ #define RETAIN_PERIPH         BIT(13)
+@@ -308,7 +313,18 @@ static int gdsc_init(struct gdsc *sc)
+        */
+       mask = HW_CONTROL_MASK | SW_OVERRIDE_MASK |
+              EN_REST_WAIT_MASK | EN_FEW_WAIT_MASK | CLK_DIS_WAIT_MASK;
+-      val = EN_REST_WAIT_VAL | EN_FEW_WAIT_VAL | CLK_DIS_WAIT_VAL;
++
++      if (!sc->en_rest_wait_val)
++              sc->en_rest_wait_val = EN_REST_WAIT_VAL;
++      if (!sc->en_few_wait_val)
++              sc->en_few_wait_val = EN_FEW_WAIT_VAL;
++      if (!sc->clk_dis_wait_val)
++              sc->clk_dis_wait_val = CLK_DIS_WAIT_VAL;
++
++      val = sc->en_rest_wait_val << EN_REST_WAIT_SHIFT |
++              sc->en_few_wait_val << EN_FEW_WAIT_SHIFT |
++              sc->clk_dis_wait_val << CLK_DIS_WAIT_SHIFT;
++
+       ret = regmap_update_bits(sc->regmap, sc->gdscr, mask, val);
+       if (ret)
+               return ret;
+diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
+index 64cdc8cf0d4d2..907396ccb83fb 100644
+--- a/drivers/clk/qcom/gdsc.h
++++ b/drivers/clk/qcom/gdsc.h
+@@ -1,6 +1,6 @@
+ /* SPDX-License-Identifier: GPL-2.0-only */
+ /*
+- * Copyright (c) 2015, 2017-2018, The Linux Foundation. All rights reserved.
++ * Copyright (c) 2015, 2017-2018, 2022, The Linux Foundation. All rights 
reserved.
+  */
+ 
+ #ifndef __QCOM_GDSC_H__
+@@ -21,6 +21,9 @@ struct reset_controller_dev;
+  * @cxcs: offsets of branch registers to toggle mem/periph bits in
+  * @cxc_count: number of @cxcs
+  * @pwrsts: Possible powerdomain power states
++ * @en_rest_wait_val: transition delay value for receiving enr ack signal
++ * @en_few_wait_val: transition delay value for receiving enf ack signal
++ * @clk_dis_wait_val: transition delay value for halting clock
+  * @resets: ids of resets associated with this gdsc
+  * @reset_count: number of @resets
+  * @rcdev: reset controller
+@@ -34,6 +37,9 @@ struct gdsc {
+       unsigned int                    clamp_io_ctrl;
+       unsigned int                    *cxcs;
+       unsigned int                    cxc_count;
++      unsigned int                    en_rest_wait_val;
++      unsigned int                    en_few_wait_val;
++      unsigned int                    clk_dis_wait_val;
+       const u8                        pwrsts;
+ /* Powerdomain allowable state bitfields */
+ #define PWRSTS_OFF            BIT(0)
+diff --git a/drivers/gpio/gpio-ts4900.c b/drivers/gpio/gpio-ts4900.c
+index 1da8d05863295..410452306bf7b 100644
+--- a/drivers/gpio/gpio-ts4900.c
++++ b/drivers/gpio/gpio-ts4900.c
+@@ -1,7 +1,7 @@
+ /*
+  * Digital I/O driver for Technologic Systems I2C FPGA Core
+  *
+- * Copyright (C) 2015 Technologic Systems
++ * Copyright (C) 2015, 2018 Technologic Systems
+  * Copyright (C) 2016 Savoir-Faire Linux
+  *
+  * This program is free software; you can redistribute it and/or
+@@ -52,19 +52,33 @@ static int ts4900_gpio_direction_input(struct gpio_chip 
*chip,
+ {
+       struct ts4900_gpio_priv *priv = gpiochip_get_data(chip);
+ 
+-      /*
+-       * This will clear the output enable bit, the other bits are
+-       * dontcare when this is cleared
++      /* Only clear the OE bit here, requires a RMW. Prevents potential issue
++       * with OE and data getting to the physical pin at different times.
+        */
+-      return regmap_write(priv->regmap, offset, 0);
++      return regmap_update_bits(priv->regmap, offset, TS4900_GPIO_OE, 0);
+ }
+ 
+ static int ts4900_gpio_direction_output(struct gpio_chip *chip,
+                                       unsigned int offset, int value)
+ {
+       struct ts4900_gpio_priv *priv = gpiochip_get_data(chip);
++      unsigned int reg;
+       int ret;
+ 
++      /* If changing from an input to an output, we need to first set the
++       * proper data bit to what is requested and then set OE bit. This
++       * prevents a glitch that can occur on the IO line
++       */
++      regmap_read(priv->regmap, offset, &reg);
++      if (!(reg & TS4900_GPIO_OE)) {
++              if (value)
++                      reg = TS4900_GPIO_OUT;
++              else
++                      reg &= ~TS4900_GPIO_OUT;
++
++              regmap_write(priv->regmap, offset, reg);
++      }
++
+       if (value)
+               ret = regmap_write(priv->regmap, offset, TS4900_GPIO_OE |
+                                                        TS4900_GPIO_OUT);
+diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h 
b/drivers/gpu/drm/sun4i/sun8i_mixer.h
+index 345b28b0a80a1..dc4300a7b019b 100644
+--- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
++++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
+@@ -114,10 +114,10 @@
+ /* format 13 is semi-planar YUV411 VUVU */
+ #define SUN8I_MIXER_FBFMT_YUV411      14
+ /* format 15 doesn't exist */
+-/* format 16 is P010 YVU */
+-#define SUN8I_MIXER_FBFMT_P010_YUV    17
+-/* format 18 is P210 YVU */
+-#define SUN8I_MIXER_FBFMT_P210_YUV    19
++#define SUN8I_MIXER_FBFMT_P010_YUV    16
++/* format 17 is P010 YVU */
++#define SUN8I_MIXER_FBFMT_P210_YUV    18
++/* format 19 is P210 YVU */
+ /* format 20 is packed YVU444 10-bit */
+ /* format 21 is packed YUV444 10-bit */
+ 
+diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c
+index cdd57ce55b2fa..9044faf0050a1 100644
+--- a/drivers/mmc/host/meson-gx-mmc.c
++++ b/drivers/mmc/host/meson-gx-mmc.c
+@@ -174,6 +174,8 @@ struct meson_host {
+       int irq;
+ 
+       bool vqmmc_enabled;
++      bool needs_pre_post_req;
++
+ };
+ 
+ #define CMD_CFG_LENGTH_MASK GENMASK(8, 0)
+@@ -655,6 +657,8 @@ static void meson_mmc_request_done(struct mmc_host *mmc,
+       struct meson_host *host = mmc_priv(mmc);
+ 
+       host->cmd = NULL;
++      if (host->needs_pre_post_req)
++              meson_mmc_post_req(mmc, mrq, 0);
+       mmc_request_done(host->mmc, mrq);
+ }
+ 
+@@ -872,7 +876,7 @@ static int meson_mmc_validate_dram_access(struct mmc_host 
*mmc, struct mmc_data
+ static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
+ {
+       struct meson_host *host = mmc_priv(mmc);
+-      bool needs_pre_post_req = mrq->data &&
++      host->needs_pre_post_req = mrq->data &&
+                       !(mrq->data->host_cookie & SD_EMMC_PRE_REQ_DONE);
+ 
+       /*
+@@ -888,22 +892,19 @@ static void meson_mmc_request(struct mmc_host *mmc, 
struct mmc_request *mrq)
+               }
+       }
+ 
+-      if (needs_pre_post_req) {
++      if (host->needs_pre_post_req) {
+               meson_mmc_get_transfer_mode(mmc, mrq);
+               if (!meson_mmc_desc_chain_mode(mrq->data))
+-                      needs_pre_post_req = false;
++                      host->needs_pre_post_req = false;
+       }
+ 
+-      if (needs_pre_post_req)
++      if (host->needs_pre_post_req)
+               meson_mmc_pre_req(mmc, mrq);
+ 
+       /* Stop execution */
+       writel(0, host->regs + SD_EMMC_START);
+ 
+       meson_mmc_start_cmd(mmc, mrq->sbc ?: mrq->cmd);
+-
+-      if (needs_pre_post_req)
+-              meson_mmc_post_req(mmc, mrq, 0);
+ }
+ 
+ static void meson_mmc_read_resp(struct mmc_host *mmc, struct mmc_command *cmd)
+diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c 
b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
+index 164988f3b4fab..a2da09da4907b 100644
+--- a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
+@@ -41,6 +41,13 @@
+ void bcmgenet_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+ {
+       struct bcmgenet_priv *priv = netdev_priv(dev);
++      struct device *kdev = &priv->pdev->dev;
++
++      if (!device_can_wakeup(kdev)) {
++              wol->supported = 0;
++              wol->wolopts = 0;
++              return;
++      }
+ 
+       wol->supported = WAKE_MAGIC | WAKE_MAGICSECURE;
+       wol->wolopts = priv->wolopts;
+diff --git a/drivers/net/ethernet/cadence/macb_main.c 
b/drivers/net/ethernet/cadence/macb_main.c
+index 0dc52cf5367e7..480d2ca369e6b 100644
+--- a/drivers/net/ethernet/cadence/macb_main.c
++++ b/drivers/net/ethernet/cadence/macb_main.c
+@@ -1283,7 +1283,14 @@ static int macb_poll(struct napi_struct *napi, int 
budget)
+       if (work_done < budget) {
+               napi_complete_done(napi, work_done);
+ 
+-              /* Packets received while interrupts were disabled */
++              /* RSR bits only seem to propagate to raise interrupts when
++               * interrupts are enabled at the time, so if bits are already
++               * set due to packets received while interrupts were disabled,
++               * they will not cause another interrupt to be generated when
++               * interrupts are re-enabled.
++               * Check for this case here. This has been seen to happen
++               * around 30% of the time under heavy network load.
++               */
+               status = macb_readl(bp, RSR);
+               if (status) {
+                       if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
+@@ -1291,6 +1298,22 @@ static int macb_poll(struct napi_struct *napi, int 
budget)
+                       napi_reschedule(napi);
+               } else {
+                       queue_writel(queue, IER, bp->rx_intr_mask);
++
++                      /* In rare cases, packets could have been received in
++                       * the window between the check above and re-enabling
++                       * interrupts. Therefore, a double-check is required
++                       * to avoid losing a wakeup. This can potentially race
++                       * with the interrupt handler doing the same actions
++                       * if an interrupt is raised just after enabling them,
++                       * but this should be harmless.
++                       */
++                      status = macb_readl(bp, RSR);
++                      if (unlikely(status)) {
++                              queue_writel(queue, IDR, bp->rx_intr_mask);
++                              if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
++                                      queue_writel(queue, ISR, 
MACB_BIT(RCOMP));
++                              napi_schedule(napi);
++                      }
+               }
+       }
+ 
+diff --git a/drivers/net/ethernet/freescale/gianfar_ethtool.c 
b/drivers/net/ethernet/freescale/gianfar_ethtool.c
+index 3c8e4e2efc070..01a7255e86c92 100644
+--- a/drivers/net/ethernet/freescale/gianfar_ethtool.c
++++ b/drivers/net/ethernet/freescale/gianfar_ethtool.c
+@@ -1489,6 +1489,7 @@ static int gfar_get_ts_info(struct net_device *dev,
+       ptp_node = of_find_compatible_node(NULL, NULL, "fsl,etsec-ptp");
+       if (ptp_node) {
+               ptp_dev = of_find_device_by_node(ptp_node);
++              of_node_put(ptp_node);
+               if (ptp_dev)
+                       ptp = platform_get_drvdata(ptp_dev);
+       }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c 
b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+index 1a7aa078f3510..6c7b364d0bf03 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+@@ -130,11 +130,8 @@ static int cmd_alloc_index(struct mlx5_cmd *cmd)
+ 
+ static void cmd_free_index(struct mlx5_cmd *cmd, int idx)
+ {
+-      unsigned long flags;
+-
+-      spin_lock_irqsave(&cmd->alloc_lock, flags);
++      lockdep_assert_held(&cmd->alloc_lock);
+       set_bit(idx, &cmd->bitmask);
+-      spin_unlock_irqrestore(&cmd->alloc_lock, flags);
+ }
+ 
+ static void cmd_ent_get(struct mlx5_cmd_work_ent *ent)
+@@ -144,17 +141,21 @@ static void cmd_ent_get(struct mlx5_cmd_work_ent *ent)
+ 
+ static void cmd_ent_put(struct mlx5_cmd_work_ent *ent)
+ {
++      struct mlx5_cmd *cmd = ent->cmd;
++      unsigned long flags;
++
++      spin_lock_irqsave(&cmd->alloc_lock, flags);
+       if (!refcount_dec_and_test(&ent->refcnt))
+-              return;
++              goto out;
+ 
+       if (ent->idx >= 0) {
+-              struct mlx5_cmd *cmd = ent->cmd;
+-
+               cmd_free_index(cmd, ent->idx);
+               up(ent->page_queue ? &cmd->pages_sem : &cmd->sem);
+       }
+ 
+       cmd_free_ent(ent);
++out:
++      spin_unlock_irqrestore(&cmd->alloc_lock, flags);
+ }
+ 
+ static struct mlx5_cmd_layout *get_inst(struct mlx5_cmd *cmd, int idx)
+diff --git a/drivers/net/ethernet/nxp/lpc_eth.c 
b/drivers/net/ethernet/nxp/lpc_eth.c
+index 3b177421651f1..d2e220a94a57c 100644
+--- a/drivers/net/ethernet/nxp/lpc_eth.c
++++ b/drivers/net/ethernet/nxp/lpc_eth.c
+@@ -1470,6 +1470,7 @@ static int lpc_eth_drv_resume(struct platform_device 
*pdev)
+ {
+       struct net_device *ndev = platform_get_drvdata(pdev);
+       struct netdata_local *pldat;
++      int ret;
+ 
+       if (device_may_wakeup(&pdev->dev))
+               disable_irq_wake(ndev->irq);
+@@ -1479,7 +1480,9 @@ static int lpc_eth_drv_resume(struct platform_device 
*pdev)
+                       pldat = netdev_priv(ndev);
+ 
+                       /* Enable interface clock */
+-                      clk_enable(pldat->clk);
++                      ret = clk_enable(pldat->clk);
++                      if (ret)
++                              return ret;
+ 
+                       /* Reset and initialize */
+                       __lpc_eth_reset(pldat);
+diff --git a/drivers/net/ethernet/qlogic/qed/qed_sriov.c 
b/drivers/net/ethernet/qlogic/qed/qed_sriov.c
+index fb9c3ca5d36cc..5e8f8eb916e64 100644
+--- a/drivers/net/ethernet/qlogic/qed/qed_sriov.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_sriov.c
+@@ -3801,11 +3801,11 @@ bool qed_iov_mark_vf_flr(struct qed_hwfn *p_hwfn, u32 
*p_disabled_vfs)
+       return found;
+ }
+ 
+-static void qed_iov_get_link(struct qed_hwfn *p_hwfn,
+-                           u16 vfid,
+-                           struct qed_mcp_link_params *p_params,
+-                           struct qed_mcp_link_state *p_link,
+-                           struct qed_mcp_link_capabilities *p_caps)
++static int qed_iov_get_link(struct qed_hwfn *p_hwfn,
++                          u16 vfid,
++                          struct qed_mcp_link_params *p_params,
++                          struct qed_mcp_link_state *p_link,
++                          struct qed_mcp_link_capabilities *p_caps)
+ {
+       struct qed_vf_info *p_vf = qed_iov_get_vf_info(p_hwfn,
+                                                      vfid,
+@@ -3813,7 +3813,7 @@ static void qed_iov_get_link(struct qed_hwfn *p_hwfn,
+       struct qed_bulletin_content *p_bulletin;
+ 
+       if (!p_vf)
+-              return;
++              return -EINVAL;
+ 
+       p_bulletin = p_vf->bulletin.p_virt;
+ 
+@@ -3823,6 +3823,7 @@ static void qed_iov_get_link(struct qed_hwfn *p_hwfn,
+               __qed_vf_get_link_state(p_hwfn, p_link, p_bulletin);
+       if (p_caps)
+               __qed_vf_get_link_caps(p_hwfn, p_caps, p_bulletin);
++      return 0;
+ }
+ 
+ static int
+@@ -4684,6 +4685,7 @@ static int qed_get_vf_config(struct qed_dev *cdev,
+       struct qed_public_vf_info *vf_info;
+       struct qed_mcp_link_state link;
+       u32 tx_rate;
++      int ret;
+ 
+       /* Sanitize request */
+       if (IS_VF(cdev))
+@@ -4697,7 +4699,9 @@ static int qed_get_vf_config(struct qed_dev *cdev,
+ 
+       vf_info = qed_iov_get_public_vf_info(hwfn, vf_id, true);
+ 
+-      qed_iov_get_link(hwfn, vf_id, NULL, &link, NULL);
++      ret = qed_iov_get_link(hwfn, vf_id, NULL, &link, NULL);
++      if (ret)
++              return ret;
+ 
+       /* Fill information about VF */
+       ivi->vf = vf_id;
+diff --git a/drivers/net/ethernet/qlogic/qed/qed_vf.c 
b/drivers/net/ethernet/qlogic/qed/qed_vf.c
+index adc2c8f3d48ef..62e4511db8575 100644
+--- a/drivers/net/ethernet/qlogic/qed/qed_vf.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_vf.c
+@@ -539,6 +539,9 @@ int qed_vf_hw_prepare(struct qed_hwfn *p_hwfn)
+                                                   p_iov->bulletin.size,
+                                                   &p_iov->bulletin.phys,
+                                                   GFP_KERNEL);
++      if (!p_iov->bulletin.p_virt)
++              goto free_pf2vf_reply;
++
+       DP_VERBOSE(p_hwfn, QED_MSG_IOV,
+                  "VF's bulletin Board [%p virt 0x%llx phys 0x%08x bytes]\n",
+                  p_iov->bulletin.p_virt,
+@@ -578,6 +581,10 @@ int qed_vf_hw_prepare(struct qed_hwfn *p_hwfn)
+ 
+       return rc;
+ 
++free_pf2vf_reply:
++      dma_free_coherent(&p_hwfn->cdev->pdev->dev,
++                        sizeof(union pfvf_tlvs),
++                        p_iov->pf2vf_reply, p_iov->pf2vf_reply_phys);
+ free_vf2pf_request:
+       dma_free_coherent(&p_hwfn->cdev->pdev->dev,
+                         sizeof(union vfpf_tlvs),
+diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c
+index 26cfe3f7ed8df..453ad1247288d 100644
+--- a/drivers/net/ethernet/ti/cpts.c
++++ b/drivers/net/ethernet/ti/cpts.c
+@@ -454,7 +454,9 @@ int cpts_register(struct cpts *cpts)
+       for (i = 0; i < CPTS_MAX_EVENTS; i++)
+               list_add(&cpts->pool_data[i].list, &cpts->pool);
+ 
+-      clk_enable(cpts->refclk);
++      err = clk_enable(cpts->refclk);
++      if (err)
++              return err;
+ 
+       cpts_write32(cpts, CPTS_EN, control);
+       cpts_write32(cpts, TS_PEND_EN, int_enable);
+diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c 
b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+index 53dbf3e28f1ef..63a2d1bcccfbc 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
++++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+@@ -1187,7 +1187,7 @@ static int xemaclite_of_probe(struct platform_device 
*ofdev)
+       if (rc) {
+               dev_err(dev,
+                       "Cannot register network device, aborting\n");
+-              goto error;
++              goto put_node;
+       }
+ 
+       dev_info(dev,
+@@ -1195,6 +1195,8 @@ static int xemaclite_of_probe(struct platform_device 
*ofdev)
+                (unsigned int __force)ndev->mem_start, lp->base_addr, 
ndev->irq);
+       return 0;
+ 
++put_node:
++      of_node_put(lp->phy_node);
+ error:
+       free_netdev(ndev);
+       return rc;
+diff --git a/drivers/net/phy/dp83822.c b/drivers/net/phy/dp83822.c
+index 8a4b1d167ce2f..ae17d2f9d5347 100644
+--- a/drivers/net/phy/dp83822.c
++++ b/drivers/net/phy/dp83822.c
+@@ -238,7 +238,7 @@ static int dp83822_config_intr(struct phy_device *phydev)
+               if (err < 0)
+                       return err;
+ 
+-              err = phy_write(phydev, MII_DP83822_MISR1, 0);
++              err = phy_write(phydev, MII_DP83822_MISR2, 0);
+               if (err < 0)
+                       return err;
+ 
+diff --git a/drivers/net/xen-netback/xenbus.c 
b/drivers/net/xen-netback/xenbus.c
+index 416305e6d0932..44e353dd2ba19 100644
+--- a/drivers/net/xen-netback/xenbus.c
++++ b/drivers/net/xen-netback/xenbus.c
+@@ -435,6 +435,7 @@ static void backend_disconnect(struct backend_info *be)
+               unsigned int queue_index;
+ 
+               xen_unregister_watchers(vif);
++              xenbus_rm(XBT_NIL, be->dev->nodename, "hotplug-status");
+ #ifdef CONFIG_DEBUG_FS
+               xenvif_debugfs_delif(vif);
+ #endif /* CONFIG_DEBUG_FS */
+@@ -979,15 +980,11 @@ static void connect(struct backend_info *be)
+       xenvif_carrier_on(be->vif);
+ 
+       unregister_hotplug_status_watch(be);
+-      if (xenbus_exists(XBT_NIL, dev->nodename, "hotplug-status")) {
+-              err = xenbus_watch_pathfmt(dev, &be->hotplug_status_watch,
+-                                         NULL, hotplug_status_changed,
+-                                         "%s/%s", dev->nodename,
+-                                         "hotplug-status");
+-              if (err)
+-                      goto err;
++      err = xenbus_watch_pathfmt(dev, &be->hotplug_status_watch, NULL,
++                                 hotplug_status_changed,
++                                 "%s/%s", dev->nodename, "hotplug-status");
++      if (!err)
+               be->have_hotplug_status_watch = 1;
+-      }
+ 
+       netif_tx_wake_all_queues(be->vif->dev);
+ 
+diff --git a/drivers/nfc/port100.c b/drivers/nfc/port100.c
+index 1caebefb25ff1..2ae1474faede9 100644
+--- a/drivers/nfc/port100.c
++++ b/drivers/nfc/port100.c
+@@ -1609,7 +1609,9 @@ free_nfc_dev:
+       nfc_digital_free_device(dev->nfc_digital_dev);
+ 
+ error:
++      usb_kill_urb(dev->in_urb);
+       usb_free_urb(dev->in_urb);
++      usb_kill_urb(dev->out_urb);
+       usb_free_urb(dev->out_urb);
+       usb_put_dev(dev->udev);
+ 
+diff --git a/drivers/staging/gdm724x/gdm_lte.c 
b/drivers/staging/gdm724x/gdm_lte.c
+index 8093d06086388..4dba62aed10b8 100644
+--- a/drivers/staging/gdm724x/gdm_lte.c
++++ b/drivers/staging/gdm724x/gdm_lte.c
+@@ -76,14 +76,15 @@ static void tx_complete(void *arg)
+ 
+ static int gdm_lte_rx(struct sk_buff *skb, struct nic *nic, int nic_type)
+ {
+-      int ret;
++      int ret, len;
+ 
++      len = skb->len + ETH_HLEN;
+       ret = netif_rx_ni(skb);
+       if (ret == NET_RX_DROP) {
+               nic->stats.rx_dropped++;
+       } else {
+               nic->stats.rx_packets++;
+-              nic->stats.rx_bytes += skb->len + ETH_HLEN;
++              nic->stats.rx_bytes += len;
+       }
+ 
+       return 0;
+diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
+index 91627e7443260..cab97cda54304 100644
+--- a/drivers/virtio/virtio.c
++++ b/drivers/virtio/virtio.c
+@@ -167,14 +167,12 @@ void virtio_add_status(struct virtio_device *dev, 
unsigned int status)
+ }
+ EXPORT_SYMBOL_GPL(virtio_add_status);
+ 
+-int virtio_finalize_features(struct virtio_device *dev)
++/* Do some validation, then set FEATURES_OK */
++static int virtio_features_ok(struct virtio_device *dev)
+ {
+-      int ret = dev->config->finalize_features(dev);
+       unsigned status;
+ 
+       might_sleep();
+-      if (ret)
+-              return ret;
+ 
+       if (!virtio_has_feature(dev, VIRTIO_F_VERSION_1))
+               return 0;
+@@ -188,7 +186,6 @@ int virtio_finalize_features(struct virtio_device *dev)
+       }
+       return 0;
+ }
+-EXPORT_SYMBOL_GPL(virtio_finalize_features);
+ 
+ static int virtio_dev_probe(struct device *_d)
+ {
+@@ -225,17 +222,6 @@ static int virtio_dev_probe(struct device *_d)
+               driver_features_legacy = driver_features;
+       }
+ 
+-      /*
+-       * Some devices detect legacy solely via F_VERSION_1. Write
+-       * F_VERSION_1 to force LE config space accesses before FEATURES_OK for
+-       * these when needed.
+-       */
+-      if (drv->validate && !virtio_legacy_is_little_endian()
+-                        && device_features & BIT_ULL(VIRTIO_F_VERSION_1)) {
+-              dev->features = BIT_ULL(VIRTIO_F_VERSION_1);
+-              dev->config->finalize_features(dev);
+-      }
+-
+       if (device_features & (1ULL << VIRTIO_F_VERSION_1))
+               dev->features = driver_features & device_features;
+       else
+@@ -246,13 +232,26 @@ static int virtio_dev_probe(struct device *_d)
+               if (device_features & (1ULL << i))
+                       __virtio_set_bit(dev, i);
+ 
++      err = dev->config->finalize_features(dev);
++      if (err)
++              goto err;
++
+       if (drv->validate) {
++              u64 features = dev->features;
++
+               err = drv->validate(dev);
+               if (err)
+                       goto err;
++
++              /* Did validation change any features? Then write them again. */
++              if (features != dev->features) {
++                      err = dev->config->finalize_features(dev);
++                      if (err)
++                              goto err;
++              }
+       }
+ 
+-      err = virtio_finalize_features(dev);
++      err = virtio_features_ok(dev);
+       if (err)
+               goto err;
+ 
+@@ -417,7 +416,11 @@ int virtio_device_restore(struct virtio_device *dev)
+       /* We have a driver! */
+       virtio_add_status(dev, VIRTIO_CONFIG_S_DRIVER);
+ 
+-      ret = virtio_finalize_features(dev);
++      ret = dev->config->finalize_features(dev);
++      if (ret)
++              goto err;
++
++      ret = virtio_features_ok(dev);
+       if (ret)
+               goto err;
+ 
+diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
+index ad1d4c8faf449..b7f20196439a2 100644
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -74,6 +74,11 @@ int ext4_resize_begin(struct super_block *sb)
+               return -EPERM;
+       }
+ 
++      if (ext4_has_feature_sparse_super2(sb)) {
++              ext4_msg(sb, KERN_ERR, "Online resizing not supported with 
sparse_super2");
++              return -EOPNOTSUPP;
++      }
++
+       if (test_and_set_bit_lock(EXT4_FLAGS_RESIZING,
+                                 &EXT4_SB(sb)->s_ext4_flags))
+               ret = -EBUSY;
+diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
+index 64d6c8c9f1ff2..ac6a8da340139 100644
+--- a/fs/fuse/dev.c
++++ b/fs/fuse/dev.c
+@@ -933,7 +933,17 @@ static int fuse_copy_page(struct fuse_copy_state *cs, 
struct page **pagep,
+ 
+       while (count) {
+               if (cs->write && cs->pipebufs && page) {
+-                      return fuse_ref_page(cs, page, offset, count);
++                      /*
++                       * Can't control lifetime of pipe buffers, so always
++                       * copy user pages.
++                       */
++                      if (cs->req->args->user_pages) {
++                              err = fuse_copy_fill(cs);
++                              if (err)
++                                      return err;
++                      } else {
++                              return fuse_ref_page(cs, page, offset, count);
++                      }
+               } else if (!cs->len) {
+                       if (cs->move_pages && page &&
+                           offset == 0 && count == PAGE_SIZE) {
+diff --git a/fs/fuse/file.c b/fs/fuse/file.c
+index 5cf13196ce69e..efb2a48712919 100644
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -1433,6 +1433,7 @@ static int fuse_get_user_pages(struct fuse_args_pages 
*ap, struct iov_iter *ii,
+                       (PAGE_SIZE - ret) & (PAGE_SIZE - 1);
+       }
+ 
++      ap->args.user_pages = true;
+       if (write)
+               ap->args.in_pages = 1;
+       else
+diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
+index d878926485451..83c2855bc7406 100644
+--- a/fs/fuse/fuse_i.h
++++ b/fs/fuse/fuse_i.h
+@@ -248,6 +248,7 @@ struct fuse_args {
+       bool nocreds:1;
+       bool in_pages:1;
+       bool out_pages:1;
++      bool user_pages:1;
+       bool out_argvar:1;
+       bool page_zeroing:1;
+       bool page_replace:1;
+diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
+index 641a01bc5f6f7..031022e326356 100644
+--- a/include/linux/mlx5/mlx5_ifc.h
++++ b/include/linux/mlx5/mlx5_ifc.h
+@@ -8975,8 +8975,8 @@ struct mlx5_ifc_bufferx_reg_bits {
+       u8         reserved_at_0[0x6];
+       u8         lossy[0x1];
+       u8         epsb[0x1];
+-      u8         reserved_at_8[0xc];
+-      u8         size[0xc];
++      u8         reserved_at_8[0x8];
++      u8         size[0x10];
+ 
+       u8         xoff_threshold[0x10];
+       u8         xon_threshold[0x10];
+diff --git a/include/linux/virtio.h b/include/linux/virtio.h
+index 7c075463c7f2b..b80376654a604 100644
+--- a/include/linux/virtio.h
++++ b/include/linux/virtio.h
+@@ -135,7 +135,6 @@ void virtio_break_device(struct virtio_device *dev);
+ void virtio_config_changed(struct virtio_device *dev);
+ void virtio_config_disable(struct virtio_device *dev);
+ void virtio_config_enable(struct virtio_device *dev);
+-int virtio_finalize_features(struct virtio_device *dev);
+ #ifdef CONFIG_PM_SLEEP
+ int virtio_device_freeze(struct virtio_device *dev);
+ int virtio_device_restore(struct virtio_device *dev);
+diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
+index bb4cc49107503..ad4d4697a1673 100644
+--- a/include/linux/virtio_config.h
++++ b/include/linux/virtio_config.h
+@@ -56,8 +56,9 @@ struct irq_affinity;
+  *    Returns the first 64 feature bits (all we currently need).
+  * @finalize_features: confirm what device features we'll be using.
+  *    vdev: the virtio_device
+- *    This gives the final feature bits for the device: it can change
++ *    This sends the driver feature bits to the device: it can change
+  *    the dev->feature bits if it wants.
++ * Note: despite the name this can be called any number of times.
+  *    Returns 0 on success or error status
+  * @bus_name: return the bus name associated with the device (optional)
+  *    vdev: the virtio_device
+diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
+index 1a89b2bf626a5..56619766e9103 100644
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -1305,10 +1305,12 @@ static int __init set_buf_size(char *str)
+       if (!str)
+               return 0;
+       buf_size = memparse(str, &str);
+-      /* nr_entries can not be zero */
+-      if (buf_size == 0)
+-              return 0;
+-      trace_buf_size = buf_size;
++      /*
++       * nr_entries can not be zero and the startup
++       * tests require some buffer space. Therefore
++       * ensure we have at least 4096 bytes of buffer.
++       */
++      trace_buf_size = max(4096UL, buf_size);
+       return 1;
+ }
+ __setup("trace_buf_size=", set_buf_size);
+diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
+index 184af6da0defc..093b73c454d28 100644
+--- a/net/ax25/af_ax25.c
++++ b/net/ax25/af_ax25.c
+@@ -87,6 +87,13 @@ again:
+       ax25_for_each(s, &ax25_list) {
+               if (s->ax25_dev == ax25_dev) {
+                       sk = s->sk;
++                      if (!sk) {
++                              spin_unlock_bh(&ax25_list_lock);
++                              s->ax25_dev = NULL;
++                              ax25_disconnect(s, ENETUNREACH);
++                              spin_lock_bh(&ax25_list_lock);
++                              goto again;
++                      }
+                       sock_hold(sk);
+                       spin_unlock_bh(&ax25_list_lock);
+                       lock_sock(sk);
+diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
+index bcad7028bbf45..ad45f13a0370b 100644
+--- a/net/core/net-sysfs.c
++++ b/net/core/net-sysfs.c
+@@ -212,7 +212,7 @@ static ssize_t speed_show(struct device *dev,
+       if (!rtnl_trylock())
+               return restart_syscall();
+ 
+-      if (netif_running(netdev)) {
++      if (netif_running(netdev) && netif_device_present(netdev)) {
+               struct ethtool_link_ksettings cmd;
+ 
+               if (!__ethtool_get_link_ksettings(netdev, &cmd))
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+index d1f29a3eb70be..60d070b254846 100644
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -4924,6 +4924,7 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct 
inet6_ifaddr *ifa,
+           nla_put_s32(skb, IFA_TARGET_NETNSID, args->netnsid))
+               goto error;
+ 
++      spin_lock_bh(&ifa->lock);
+       if (!((ifa->flags&IFA_F_PERMANENT) &&
+             (ifa->prefered_lft == INFINITY_LIFE_TIME))) {
+               preferred = ifa->prefered_lft;
+@@ -4945,6 +4946,7 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct 
inet6_ifaddr *ifa,
+               preferred = INFINITY_LIFE_TIME;
+               valid = INFINITY_LIFE_TIME;
+       }
++      spin_unlock_bh(&ifa->lock);
+ 
+       if (!ipv6_addr_any(&ifa->peer_addr)) {
+               if (nla_put_in6_addr(skb, IFA_LOCAL, &ifa->addr) < 0 ||
+diff --git a/net/sctp/diag.c b/net/sctp/diag.c
+index 7921e77fa55a3..5a918e74bb82b 100644
+--- a/net/sctp/diag.c
++++ b/net/sctp/diag.c
+@@ -61,10 +61,6 @@ static void inet_diag_msg_sctpasoc_fill(struct 
inet_diag_msg *r,
+               r->idiag_timer = SCTP_EVENT_TIMEOUT_T3_RTX;
+               r->idiag_retrans = asoc->rtx_data_chunks;
+               r->idiag_expires = jiffies_to_msecs(t3_rtx->expires - jiffies);
+-      } else {
+-              r->idiag_timer = 0;
+-              r->idiag_retrans = 0;
+-              r->idiag_expires = 0;
+       }
+ }
+ 
+@@ -144,13 +140,14 @@ static int inet_sctp_diag_fill(struct sock *sk, struct 
sctp_association *asoc,
+       r = nlmsg_data(nlh);
+       BUG_ON(!sk_fullsock(sk));
+ 
++      r->idiag_timer = 0;
++      r->idiag_retrans = 0;
++      r->idiag_expires = 0;
+       if (asoc) {
+               inet_diag_msg_sctpasoc_fill(r, sk, asoc);
+       } else {
+               inet_diag_msg_common_fill(r, sk);
+               r->idiag_state = sk->sk_state;
+-              r->idiag_timer = 0;
+-              r->idiag_retrans = 0;
+       }
+ 
+       if (inet_diag_msg_attrs_fill(sk, skb, r, ext, user_ns, net_admin))
+diff --git a/tools/testing/selftests/bpf/prog_tests/timer_crash.c 
b/tools/testing/selftests/bpf/prog_tests/timer_crash.c
+new file mode 100644
+index 0000000000000..f74b82305da8c
+--- /dev/null
++++ b/tools/testing/selftests/bpf/prog_tests/timer_crash.c
+@@ -0,0 +1,32 @@
++// SPDX-License-Identifier: GPL-2.0
++#include <test_progs.h>
++#include "timer_crash.skel.h"
++
++enum {
++      MODE_ARRAY,
++      MODE_HASH,
++};
++
++static void test_timer_crash_mode(int mode)
++{
++      struct timer_crash *skel;
++
++      skel = timer_crash__open_and_load();
++      if (!ASSERT_OK_PTR(skel, "timer_crash__open_and_load"))
++              return;
++      skel->bss->pid = getpid();
++      skel->bss->crash_map = mode;
++      if (!ASSERT_OK(timer_crash__attach(skel), "timer_crash__attach"))
++              goto end;
++      usleep(1);
++end:
++      timer_crash__destroy(skel);
++}
++
++void test_timer_crash(void)
++{
++      if (test__start_subtest("array"))
++              test_timer_crash_mode(MODE_ARRAY);
++      if (test__start_subtest("hash"))
++              test_timer_crash_mode(MODE_HASH);
++}
+diff --git a/tools/testing/selftests/bpf/progs/timer_crash.c 
b/tools/testing/selftests/bpf/progs/timer_crash.c
+new file mode 100644
+index 0000000000000..f8f7944e70dae
+--- /dev/null
++++ b/tools/testing/selftests/bpf/progs/timer_crash.c
+@@ -0,0 +1,54 @@
++// SPDX-License-Identifier: GPL-2.0
++
++#include <vmlinux.h>
++#include <bpf/bpf_tracing.h>
++#include <bpf/bpf_helpers.h>
++
++struct map_elem {
++      struct bpf_timer timer;
++      struct bpf_spin_lock lock;
++};
++
++struct {
++      __uint(type, BPF_MAP_TYPE_ARRAY);
++      __uint(max_entries, 1);
++      __type(key, int);
++      __type(value, struct map_elem);
++} amap SEC(".maps");
++
++struct {
++      __uint(type, BPF_MAP_TYPE_HASH);
++      __uint(max_entries, 1);
++      __type(key, int);
++      __type(value, struct map_elem);
++} hmap SEC(".maps");
++
++int pid = 0;
++int crash_map = 0; /* 0 for amap, 1 for hmap */
++
++SEC("fentry/do_nanosleep")
++int sys_enter(void *ctx)
++{
++      struct map_elem *e, value = {};
++      void *map = crash_map ? (void *)&hmap : (void *)&amap;
++
++      if (bpf_get_current_task_btf()->tgid != pid)
++              return 0;
++
++      *(void **)&value = (void *)0xdeadcaf3;
++
++      bpf_map_update_elem(map, &(int){0}, &value, 0);
++      /* For array map, doing bpf_map_update_elem will do a
++       * check_and_free_timer_in_array, which will trigger the crash if timer
++       * pointer was overwritten, for hmap we need to use bpf_timer_cancel.
++       */
++      if (crash_map == 1) {
++              e = bpf_map_lookup_elem(map, &(int){0});
++              if (!e)
++                      return 0;
++              bpf_timer_cancel(&e->timer);
++      }
++      return 0;
++}
++
++char _license[] SEC("license") = "GPL";
+diff --git a/tools/testing/selftests/memfd/memfd_test.c 
b/tools/testing/selftests/memfd/memfd_test.c
+index c67d32eeb668e..290cec2a6a338 100644
+--- a/tools/testing/selftests/memfd/memfd_test.c
++++ b/tools/testing/selftests/memfd/memfd_test.c
+@@ -421,6 +421,7 @@ static void mfd_fail_write(int fd)
+                       printf("mmap()+mprotect() didn't fail as expected\n");
+                       abort();
+               }
++              munmap(p, mfd_def_size);
+       }
+ 
+       /* verify PUNCH_HOLE fails */
+diff --git a/tools/testing/selftests/net/pmtu.sh 
b/tools/testing/selftests/net/pmtu.sh
+index 3429767cadcdd..88be9083b923b 100755
+--- a/tools/testing/selftests/net/pmtu.sh
++++ b/tools/testing/selftests/net/pmtu.sh
+@@ -579,7 +579,6 @@ setup_routing() {
+ setup() {
+       [ "$(id -u)" -ne 0 ] && echo "  need to run as root" && return 
$ksft_skip
+ 
+-      cleanup
+       for arg do
+               eval setup_${arg} || { echo "  ${arg} not supported"; return 1; 
}
+       done
+@@ -590,7 +589,7 @@ trace() {
+ 
+       for arg do
+               [ "${ns_cmd}" = "" ] && ns_cmd="${arg}" && continue
+-              ${ns_cmd} tcpdump -s 0 -i "${arg}" -w "${name}_${arg}.pcap" 2> 
/dev/null &
++              ${ns_cmd} tcpdump --immediate-mode -s 0 -i "${arg}" -w 
"${name}_${arg}.pcap" 2> /dev/null &
+               tcpdump_pids="${tcpdump_pids} $!"
+               ns_cmd=
+       done
+@@ -1182,6 +1181,10 @@ run_test() {
+ 
+       unset IFS
+ 
++      # Since cleanup() relies on variables modified by this subshell, it
++      # has to run in this context.
++      trap cleanup EXIT
++
+       if [ "$VERBOSE" = "1" ]; then
+               printf 
"\n##########################################################################\n\n"
+       fi
+diff --git a/tools/testing/selftests/vm/map_fixed_noreplace.c 
b/tools/testing/selftests/vm/map_fixed_noreplace.c
+index d91bde5112686..eed44322d1a63 100644
+--- a/tools/testing/selftests/vm/map_fixed_noreplace.c
++++ b/tools/testing/selftests/vm/map_fixed_noreplace.c
+@@ -17,9 +17,6 @@
+ #define MAP_FIXED_NOREPLACE 0x100000
+ #endif
+ 
+-#define BASE_ADDRESS  (256ul * 1024 * 1024)
+-
+-
+ static void dump_maps(void)
+ {
+       char cmd[32];
+@@ -28,18 +25,46 @@ static void dump_maps(void)
+       system(cmd);
+ }
+ 
++static unsigned long find_base_addr(unsigned long size)
++{
++      void *addr;
++      unsigned long flags;
++
++      flags = MAP_PRIVATE | MAP_ANONYMOUS;
++      addr = mmap(NULL, size, PROT_NONE, flags, -1, 0);
++      if (addr == MAP_FAILED) {
++              printf("Error: couldn't map the space we need for the test\n");
++              return 0;
++      }
++
++      if (munmap(addr, size) != 0) {
++              printf("Error: couldn't map the space we need for the test\n");
++              return 0;
++      }
++      return (unsigned long)addr;
++}
++
+ int main(void)
+ {
++      unsigned long base_addr;
+       unsigned long flags, addr, size, page_size;
+       char *p;
+ 
+       page_size = sysconf(_SC_PAGE_SIZE);
+ 
++      //let's find a base addr that is free before we start the tests
++      size = 5 * page_size;
++      base_addr = find_base_addr(size);
++      if (!base_addr) {
++              printf("Error: couldn't map the space we need for the test\n");
++              return 1;
++      }
++
+       flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED_NOREPLACE;
+ 
+       // Check we can map all the areas we need below
+       errno = 0;
+-      addr = BASE_ADDRESS;
++      addr = base_addr;
+       size = 5 * page_size;
+       p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
+ 
+@@ -60,7 +85,7 @@ int main(void)
+       printf("unmap() successful\n");
+ 
+       errno = 0;
+-      addr = BASE_ADDRESS + page_size;
++      addr = base_addr + page_size;
+       size = 3 * page_size;
+       p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
+       printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
+@@ -80,7 +105,7 @@ int main(void)
+        *     +4 |  free  | new
+        */
+       errno = 0;
+-      addr = BASE_ADDRESS;
++      addr = base_addr;
+       size = 5 * page_size;
+       p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
+       printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
+@@ -101,7 +126,7 @@ int main(void)
+        *     +4 |  free  |
+        */
+       errno = 0;
+-      addr = BASE_ADDRESS + (2 * page_size);
++      addr = base_addr + (2 * page_size);
+       size = page_size;
+       p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
+       printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
+@@ -121,7 +146,7 @@ int main(void)
+        *     +4 |  free  | new
+        */
+       errno = 0;
+-      addr = BASE_ADDRESS + (3 * page_size);
++      addr = base_addr + (3 * page_size);
+       size = 2 * page_size;
+       p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
+       printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
+@@ -141,7 +166,7 @@ int main(void)
+        *     +4 |  free  |
+        */
+       errno = 0;
+-      addr = BASE_ADDRESS;
++      addr = base_addr;
+       size = 2 * page_size;
+       p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
+       printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
+@@ -161,7 +186,7 @@ int main(void)
+        *     +4 |  free  |
+        */
+       errno = 0;
+-      addr = BASE_ADDRESS;
++      addr = base_addr;
+       size = page_size;
+       p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
+       printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
+@@ -181,7 +206,7 @@ int main(void)
+        *     +4 |  free  |  new
+        */
+       errno = 0;
+-      addr = BASE_ADDRESS + (4 * page_size);
++      addr = base_addr + (4 * page_size);
+       size = page_size;
+       p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
+       printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
+@@ -192,7 +217,7 @@ int main(void)
+               return 1;
+       }
+ 
+-      addr = BASE_ADDRESS;
++      addr = base_addr;
+       size = 5 * page_size;
+       if (munmap((void *)addr, size) != 0) {
+               dump_maps();

Reply via email to